Path-based routing (History API)
By default, @bmlt-enabled/svelte-spa-router uses hash-based routing (e.g. http://example.com/#/books). If you prefer clean URLs without the hash fragment, you can switch to path-based routing using the HTML5 History API. This is a feature added by this BMLT fork on top of the original upstream project.
Enabling path mode
Set the hashMode prop to false on the Router component:
<script>
import Router from '@bmlt-enabled/svelte-spa-router'
const routes = {
'/': Home,
'/books': Books,
'*': NotFound,
}
</script>
<Router {routes} hashMode={false} />
With this configuration, URLs will look like http://example.com/books instead of http://example.com/#/books.
Programmatic configuration
You can also set the routing mode programmatically using setHashMode, which is useful if you need to configure the mode before the Router component mounts:
import { setHashMode } from '@bmlt-enabled/svelte-spa-router'
// Switch to path-based routing
setHashMode(false)
Base path
When your app is served under a sub-path (e.g. example.com/meetings/), you can set a basePath so the router automatically strips it from incoming URLs and prepends it to outgoing ones:
<Router {routes} hashMode={false} basePath="/meetings" />
Or programmatically:
import { setHashMode } from '@bmlt-enabled/svelte-spa-router'
setHashMode(false, '/meetings')
With basePath="/meetings":
push('/book/42')navigates to/meetings/book/42router.locationreturns/book/42
Your app code never needs to know about the prefix — you always work with paths relative to the base.
What stays the same
All other APIs work identically in both modes:
- Route definitions use the same syntax (
/,/books,/user/:id,*) push(),pop(),replace()accept the same path format (e.g.push('/books'))use:linkworks the same way:<a href="/books" use:link>use:activeworks the same wayrouter.location,router.querystring,router.paramsall work the same- Route pre-conditions,
wrap(), and callbacks all work the same
Server configuration
When using path-based routing, your server must be configured to serve your index.html for all routes (SPA fallback). Without this, refreshing the page or navigating directly to a URL like /books will result in a 404 from the server, since no file exists at that path.
Common server configurations:
Nginx
location / {
try_files $uri $uri/ /index.html;
}
Apache (.htaccess)
FallbackResource /index.html
Netlify (_redirects)
/* /index.html 200
Vercel (vercel.json)
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}
Cloudflare Pages
Cloudflare Pages serves SPA fallbacks automatically for single-page apps, but you can make it explicit by adding a _redirects file to your build output:
/* /index.html 200
Vite dev server
Handles SPA fallback by default — no extra configuration needed.