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>
)
}