Introduction

I’ve covered this before, but I’ll repeat myself: moving to SharePoint Online isn’t just about moving your documents.

You also need to move your users.

Not physically, of course. But you need to help your users transition to the new platform, and it should be as painless as possible for them.

You should spend some time preparing your users for the upcoming changes, educating them and answering their questions. Because, for most users, change is a scary thing.

But even if you spend countless hours educating your users and holding their hands through the migration process, they may still have bookmarks to content that you moved from your on-premises SharePoint server to SharePoint Online. They may have shortcuts and favorites?

Some of the documents that you migrated may have links to your old on-premises SharePoint installation. Are you going to update every single document that contain hyperlinks to the old SharePoint site?

And how can you whether your users are still trying to go to old on-prem SharePoint links that are no longer there?

In today’s post, we’ll bring an old feature back from the dead to help make your migration to SharePoint Online a lot easier for you and your users.

It only works in situations where you keep your old SharePoint on-premises (2013, 2016, and 2019) server up and running while you migrate the content from it to your SharePoint Online instance.

Best of all, you won’t need to install any Dlls, Sandbox solutions, or Add-ons on your servers.

The original sharepointsmart404

Back in 2009 a brilliant person by the name of Josh Carlisle created a cool solution called sharepointsmart404. It enhanced the out-of-the-box SharePoint "Page Not Found" error (also known as a 404 error) to provide support for vanity URLs.

A vanity URL, in case you’re wondering, is a unique URL branded for marketing purposes. Instead of using long and ugly URLs, you can use shorter, easier to remember URLs.

With smart 404, when people looked for a page or document that was no longer there, SharePoint would redirect them to the new location of that page/document as long as it found a matching vanity URL.

NOTE: If you are the author of the original sharepointsmart404, or know the original author, I would like to link to their profile and give them credit. Please contact me, and I’ll make sure to update this post.

Here is how the feature worked:

  • When someone asks for a SharePoint URL which does not exist, SharePoint redirects to the 404 error page
  • The feature intercepts the 404 error and looks for the requested URL against a list of vanity URLs. Each vanity URL entry consists of a requestURL (the URL that caused the page not found error), and a redirectURL (the URL where users should be redirected).
  • If there is a matching vanity URL, redirect users to the redirectURL and don’t display the "Page Not Found" message
  • If there isn’t a matching vanity URL, display the "Page Not Found" message

This is the process there is a matching vanity URL:

sequenceDiagram
Browser -->> ASP.NET: Requests a page
ASP.NET -->> SharePoint: Requests document by URL
SharePoint -->> ASP.NET: Page not found, return 404
ASP.NET -->> Smart 404: Do you have any entries for this URL?
Note right of Smart 404: Found a matching vanity URL
Smart 404 -->> ASP.NET: Returns a matching vanity URL
ASP.NET -->> Browser: Redirect to vanity URL

This is the process when there are no matching vanity URLs:

sequenceDiagram
Browser -->> ASP.NET: Requests a page
ASP.NET -->> SharePoint: Requests document by URL
SharePoint -->> ASP.NET: Page not found, return 404
ASP.NET -->> Smart 404: Do you have any entries for this URL?
Note right of Smart 404: No matching vanity URL
Smart 404 -->> ASP.NET: Return page not found
ASP.NET -->> Browser: Display page not found error page

Unfortunately, the original smart 404 is no longer maintained and does not work on SharePoint 2013 or newer.

But the idea was brilliant. So much so that nearly 10 years later, I haven’t forgotten about it.

Bringing Smart 404 back from the dead

I set out to re-create the smart 404 to help anyone who wants to migrate from SharePoint 2013, 2016, or 2019 to SharePoint Online.

The original version used an ASP.NET HttpModule to intercept the request and required deploying DLLs to the server; I wanted to re-create it without using any custom DLLs, Add-ins, or anything of the sort.

To make the solution easier to deploy on any version of SharePoint 2013 or later, I’ll provide the steps to create the required lists and deploy the feature using out-of-the-box features of SharePoint. The instructions should work for 2013, 2016, or 2019, but I was only able to test it in 2013 and 2019. Let me know if you find any issues.

You can also download the web part and list templates from my repo if you’d like.

Leveraging PageNotFoundError.aspx

Since SharePoint 2013, all 404 errors result in SharePoint displaying the PageNotFoundError.aspx, located in the Pages library of the root SharePoint site.

When SharePoint redirects a request to the PageNotFoundError.aspx page, it adds a query string parameter called requestUrl, which contains the request URL (and caused a 404 error).

So if you requested a page called WheresMyStuff on your sharepoint.contoso.com server which resulted in a 404 error, SharePoint would redirect you to:

https://sharepoint.consoso.com/Pages/PageNotFoundError.aspx?requestUrl=https://sharepoint.contoso.com/WheresMyStuff

But here is the secret: the PageNotFoundError.aspx is a standard SharePoint web part page!

And our Smart 404 is just a regular good ol’ web part on that page!

The new Smart 404 solution

There are three elements to the Smart 404 solution:

  • The VanityURLs list: A list which maps a redirectUrl for each requestUrl.
  • The RedirectLog list: A list which records when the Smart 404 Web Part displays, the requested URL , who requested it, and what the outcome was.
  • The Smart 404 Web Part: A Content Editor Web Part that points to an HTML page with Javascript, which redirects the user or displays a "Page Not Found" message.

Let’s explore each component in details.

The Smart 404 Web Part

The Smart 404 Web Part uses the Content Editor Web Part to embed some HTML in the PageNotFoundError.aspx page.

The HTML has some Javascript which performs the following steps:

  • When the page loads, it looks to see if there is a requestUrl parameter in the query string.
  • If there is a requestUrl, it looks for a matching entry in the SmartRedirects list.
  • If it finds a matching requestURL, it redirects the user to the matching redirectURL on SharePoint Online. It also creates an entry in the RedirectLogs list so that we can keep track of where we’re redirecting users.
  • If it does not find a matching requestURL, it displays the "Page Not Found" error message (or, optionally, it redirects to the SharePoint Online search page). It also creates a record in the RedirectLogs list to record any potentially missing vanity URLs.

The updated sequence diagram looks as follows:

sequenceDiagram
Browser -->> SharePoint: Requests a page
SharePoint -->> Browser: Page not found, redirect to PageNotFoundError.aspx
PageNotFoundError.aspx -->> Smart 404 Web Part: Do you have any redirect entries for this URL?
Note right of Smart 404 Web Part: Found a matching redirect URL
Smart 404 Web Part -->> Browser: Redirect to new URL

When looking for a match, the Smart 404 uses the following logic:

st=>start: Start
e=>end: End
op1=>operation: Look for exact match
sub1=>subroutine: My Subroutine
cond=>condition: Exact match found?
op2=>operation: Look for 'Starts With' match
cond2=>condition: Starts With match found?
io=>inputoutput: Redirect
op3=>operation:  Look for Regular Expression match
cond3=>condition: Regular Expression match found?
ionf=>inputoutput: Display 'Page Not Found'

st->op1->cond
cond(yes)->io->e
cond(no, bottom)->op2->cond2
cond2(yes)->io->e
cond2(no, bottom)->op3->cond3
cond3(yes)->io->e
cond3(no, bottom)->ionf->e

The VanityURLs List

The VanityURLs list is a very simple list. It contains the following fields:

  • Title: A friendly title for your redirect. Not used by the web part, but helps make your list of Vanity URLs manageable.
  • RequestURL: A text field containing the original URL of a resource.
  • RedirectURL: The URL where you wish to redirect users when there is a matching RequestURL
  • RedirectType: A choice field describing what type of redirect to use. The valid choices are either Exact Match, Begins With or Regular Expression
  • RegExp: The regular expression to be used for Regular Expression matches
  • Order: The priority for this vanity URL when more than one vanity URL matches the current URL

The RedirectLog List

The RedirectLog list contains the following fields:

  • Title: A simple text description of the outcome.
  • RequestURL: The URL that was requested.
  • Referrer: The HTTP Referrer (in case we were directed from somewhere else)
  • RedirectedTo: The URL where we sent the user.
  • Outcome:: Keeps track of whether users were redirected due to an exact match, a partial match, or if they were redirected to the search page because there weren’t any matching Vanity URLs.

The list also contains the standard Created, CreatedBy, Modified, ModifiedBy fields, which are used to record who and when the redirection occurred.

Once you deploy the Smart 404 Web Part, you can monitor the logs and look for the following patterns:

  • Large numbers of No Match outcomes: Means that users are still trying to go to your old on-premises SharePoint server without a matching RedirectURL. You should consider finding where the content matching the RequestURL was relocated and create a new SmartRedirects item to redirect them to the right place.
  • Many entries to the same RequestURL from multiple users: This means that somewhere out there, there is an old shortcut pointing to the on-premises SharePoint server that hasn’t been updated. It could be an existing system, a link in a document, etc. Look at the Referrer to see if they came from the same place.
  • Many entries from the same user: This means that someone is being stubborn and has not updated their shortcuts to point to the new SharePoint Online tenant. They may simply need your help with updating their records.
  • A decline in the frequency of records/no more records: This means that fewer people are trying to go to the old on-premises SharePoint server and that you should consider retiring your server without impacting your users.

To deploy the Smart 404 solution

As promised earlier, the Smart 404 solution does not require deploying any DLLs or add-ins to your servers. You simply need to create the required lists, add the Content Editor Web Part to your PageNotFoundError.aspx page, and start adding some entries in your SmartRedirects list.

The detailed instructions, along with the code for the Smart 404 Web Part, can be found on my Smart 404 repository, but he’s the summary:

  • Make changes to the Smart404.html page as necessary to meet your own needs. For example, you can change the look and feel of the "Page Not Found" content template, or the "Your File Has Moved" template.
  • Upload the modified Smart404.html page to your root site’s Site Assets folder
  • Create the VanityURLs and RedirectLog lists (manually or using the list templates from the repo)
  • Add a content viewer web part that points to your /SiteAssets/Smart404.html page to your PageNotFoundError.aspx

Conclusion

The process of migrating your SharePoint content from on-premises to SharePoint Online can take a while. During that time, your users may have shortcuts that point them to the old SharePoint instance.

The Smart 404 is a simple solution you can deploy on your on-premises SharePoint server that will replace the standard "Page Not Found" behavior of your SharePoint on-premises server to redirect users to the SharePoint Online equivalent of the content they were looking for.

Thanks

  • Thanks to Gary Rong for helping build the code, and Rodney Hayden for being a test subject volunteer participant,
  • Credit goes to Josh Carlisle for the original sharepointsmart404.

Updates

  • December 16, 2019: Gary Rong added logic to handle Regular Expressions and helped identify issues with the code in Internet Explorer, because — apparently — people still use IE?!?!.
Author

Microsoft MVP and PnP Team Member. Independent consultant. Certified SCRUM Master. SharePoint, Office 365 and Dynamics 365 are his favourite toys.

How can I help?

This site uses Akismet to reduce spam. Learn how your comment data is processed.