How to get SPA routing fallbacks?
How do I make the server fall back to the index.html for any non-covered route, in the SPA mode?
This is needed to use libraries like react-router.
I tried adding this:
app.get('/*', {
logLevel: 'warn',
handler: (_, reply) => {
return reply.html();
},
});
This works fine in dev mode, but in production mode, it clashes with static path handlers.
Error: Method 'HEAD' already declared for route '/*' with constraints '{}'
at Router._on (/home/panta/dev/authoredin/danaway/node_modules/fastify/node_modules/find-my-way/index.js:301:13)
at Router.on (/home/panta/dev/authoredin/danaway/node_modules/fastify/node_modules/find-my-way/index.js:149:10)
at Object.addNewRoute (/home/panta/dev/authoredin/danaway/node_modules/fastify/lib/route.js:336:16)
at Object.route (/home/panta/dev/authoredin/danaway/node_modules/fastify/lib/route.js:247:19)
at Object._route [as route] (/home/panta/dev/authoredin/danaway/node_modules/fastify/fastify.js:288:27)
at fastifyStatic (/home/panta/dev/authoredin/danaway/node_modules/@fastify/static/index.js:115:15)
at Plugin.exec (/home/panta/dev/authoredin/danaway/node_modules/fastify/node_modules/avvio/lib/plugin.js:125:28)
at Boot._loadPlugin (/home/panta/dev/authoredin/danaway/node_modules/fastify/node_modules/avvio/boot.js:432:10)
at processTicksAndRejections (node:internal/process/task_queues:82:21)
It seems examples don't cover this. Eg. take this example: https://github.com/FrancoRATOVOSON/fastify-vite-examples/tree/main/fastify-vite/react-vanilla-spa
Install react-router.
Modify the App.tsx file like this:
import './App.css'
import { createBrowserRouter, Link, RouterProvider } from 'react-router';
function A() {
return (
<div className='w-full flex justify-center gap-16 mb-10'>
<h1>A</h1>
<Link to={'/'}>Back</Link>
</div>
)
}
function B() {
return (
<div className='w-full flex justify-center gap-16 mb-10'>
<h1>B</h1>
<Link to={'/'}>Back</Link>
</div>
)
}
function Menu() {
return <div>
<p><Link to={'/a'}>A</Link></p>
<p><Link to={'/b'}>B</Link></p>
</div>;
}
const router = createBrowserRouter([
{
path: '/',
element: <Menu />,
},
{
path: '/a',
element: <A />,
},
{
path: '/b',
element: <B />,
},
]
);
function App() {
return <RouterProvider router={router}/>
}
export default App
Build & run & open in browser. All the links between A and B will work. But if you go to /a, for example, and then reload, the page will crash.
If you are using the example you linked, could you please try and update @fastify/vite to the latest version? An issue with serving public files using a wildcard route was fixed since the version in that repo