Home > Back-end >  Nextjs Router: Redirect hash routes to non hash routes
Nextjs Router: Redirect hash routes to non hash routes

Time:06-07

I recently migrated React application to nextjs.

There we exchanged the HashRouter with the nextjs Router.

When someone deep links to our page I want that the Urls are forwarded to the routes without the #.

Example: Forward /#/contact to /contact

Redirecting within next.config.js

First I tried the following within next.config.js:

module.exports = {
  async redirects() {
    return [
      {
        source: '/#/:slug*',
        destination: '/:slug*',
        permanent: true
      }
    ]
  }
}

--> But this does not work as the next router ignores the # part of the url.

Redirect within _app.tsx

Then I wrote an custom hook useHashRouterRedirects.ts.

import { useEffect } from 'react'
import { useRouter } from 'next/router'

/**
 * Redirecting the old routes # router URLs to the new nextjs urls.
 * (This does not work within the next.config.js)
 */
export const useHashRouterRedirects = () => {
  const { push } = useRouter()

  useEffect(() => {
    const hashRoute = window.location.hash
    if (hashRoute.includes('#')) {
      const routeWithoutHash = hashRoute.replace('#', '')
      push(routeWithoutHash)
    }
  }, [])
}

and then import it within _app.tsx

useHashRouterRedirects()

--> But this loads first the old page and then the new page. It should forward the URLs quicker.

What's better?

Is there any other option on how I can redirect the # routes?

CodePudding user response:

Hash routes can only be handled on the client side.

The following solution immediately redirects and does not load the previous page first.

Add a new file inside the public folder.

public/hash-router-redirect.js

if (window.location.hash.includes('#')) {
    const routeWithoutHash = window.location.hash.replace('#', '')
    window.location.replace(routeWithoutHash)
}

Inside your pages folder navigate to or create) _document.js

webview/src/pages/_document.tsx

import { Html, Head, Main, NextScript } from 'next/document'

export default function Document() {
  return (
    <Html>
      <Head>
        ...
        <script async type='text/javascript' src='/hash-router-redirect.js'></script>
      </Head>
      <body>
        <Main />
        <NextScript />
      </body>
    </Html>
  )
}

  • Related