My App

Spa Fallback

SPA Fallback

SPA fallback ensures client-side routes work in production by serving index.html for non-API, non-static routes.

How It Works

When a request doesn't match:

  • /api/* (API routes)
  • /assets/* (static files)
  • Any path containing . (static file extension)

The server serves index.html, letting the client router handle the route.

Example

RequestResponse
GET /index.html
GET /aboutindex.html
GET /users/123index.html
GET /api/healthAPI response
GET /assets/client.jsStatic file
GET /favicon.png404 (not found)

Configuration

import { dexSpaFallback } from '@dex/server'

app.use(dexSpaFallback({
  // Default: skip /api/*, /assets/*, paths with .
  skip: ['/api', '/assets']
}))

Client Router

The client router (@dex/router/client) handles these routes:

import { BrowserRouter } from '@dex/router/client'

export default function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/:slug" element={<Page />} />
      </Routes>
    </BrowserRouter>
  )
}

See Also

On this page