Appearance
Self-hosting with dynamic URL path parameters
WeWeb apps are Vue.js Single‑Page Applications (SPAs).
When deploying to static hosting providers such as Cloudflare, Netlify, or Vercel, you may notice:
- ✔️ Navigating to a page with a dynamic path parameter works (e.g.,
/category → /category/{variable}) - ❌ Refreshing a page with a dynamic path parameter returns a 404
This is not a bug in your code — it’s a routing configuration issue.
In Simple Terms
Think of your WeWeb app as a hotel where index.html is the Reception Desk.
- When you click links inside the app: You are already in the hotel. The receptionist guides you to different rooms (pages) instantly. You don't need to ask the hotel security (the server) for permission.
- When you refresh or share a link: You are arriving from outside. You ask the security guard for specific access (e.g. "Room 101").
- The Problem: In a Single-Page Application (SPA), "Room 101" doesn't technically exist as a separate physical room; it's created virtually by the receptionist. The guard checks his list, doesn't see "Room 101", and says "404 Not Found".
- The Solution: You give the guard a new instruction: "If someone asks for a room number I don't know, just send them to the Reception Desk (
index.html). The receptionist will handle it."
Understanding Your Build Structure
The build you get with your Vue.js application will have an index.html file at the root and other index files for every page. Usually, the root index is called when you start from the home page, but you may need to access a page directly. In that case, the specific index.html file for that page must be served.
Your Build Output Structure
After running npm run build, your dist folder contains:
dist/
├── index.html # Homepage (root)
├── assets/ # JavaScript, CSS, fonts
├── data/ # JSON data files
├── products/
│ └── index.html # Products listing page
└── product/
└── :param/
└── details/
└── index.html # Product details page templateEach index.html file contains:
- Specific metadata (title, description, Open Graph tags)
- The same Vue.js application code (in
assets/main-*.js) - Different initial page data
The Challenge: URLs with Parameters
Notice the :param folder in the structure above? This is a literal folder name, not a dynamic parameter. It serves as a template for all product pages.
You have:
- One template file:
/product/:param/details/index.html - Many possible URLs:
/product/1/details,/product/5/details,/product/99/details, etc.
When a user directly visits /product/5/details:
Without proper routing:
- ❌ Server looks for
/product/5/details/index.html→ doesn't exist → 404 error - ❌ Wrong metadata loaded (or none at all)
- ❌ Search engines and social media see incorrect information
With proper routing:
- ✅ Server maps
/product/5/details→/product/:param/details/index.html - ✅ Correct metadata served
- ✅ Social sharing work perfectly
- ✅ Vue app loads and renders product #5
Why This Matters
- Routing reliability: Direct links to dynamic URLs (like
/product/5/details) don’t 404; the correct HTML file can be served. - User experience: Page refreshes keep users on the right route, and back/forward navigation continues to work.
Solutions For other providers
The solution depends on your provider. To fix this, you need a specific routing rule to ensure the proper index.html is loaded.
Cloudflare
To self‑host your WeWeb app on Cloudflare, we recommend using Cloudflare Pages.
If you deploy a static site without adding a 404.html, Cloudflare Pages may detect you are deploying an SPA and will serve your index.html for paths that don’t match a file. As a result, the exported WeWeb app can work as is, with no manual custom routing needed on your side.
We have documented the step‑by‑step process here:
- Cloudflare guide: https://docs.weweb.io/settings-billing-code-export/cloudflare-self-hosting-guide.html
Pro tip: If you add a 404.html or you want to make SPA fallback explicit, include a _redirects file at the project root:
txt
/* /index.html 200This ensures any unknown path is served index.html, letting the Vue router handle it.
Vercel
To properly serve pages with dynamic path parameters when you self‑host your WeWeb app on Vercel, add a vercel.json file at the root of your exported app:

The code inside the vercel.json would be something like this:
json
{
"rewrites": [{ "source": "/(.*)", "destination": "/index.html" }]
}This snippet will work for a straightforward use case. However, for advanced SEO optimization of dynamic routes (serving the :param template instead of root), you may need to add more specific rewrite rules matching your URL patterns.
Docs: https://vercel.com/docs/project-configuration#rewrites
If you also have API routes and want to exclude them from the SPA fallback, put those rules first:
json
{
"rewrites": [
{ "source": "/api/(.*)", "destination": "/api/$1" },
{ "source": "/(.*)", "destination": "/index.html" }
]
}Netlify
To properly serve pages with dynamic path parameters when you self‑host your WeWeb app on Netlify, add a netlify.toml file at the root of your exported app:

The code inside the netlify.toml would be something like this:
toml
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Docs: https://docs.netlify.com/manage/routing/redirects/overview/
If you also have API routes and want to exclude them from the SPA fallback, add those rules above the fallback:
toml
[[redirects]]
from = "/api/*"
to = "/api/:splat"
status = 200
[[redirects]]
from = "/*"
to = "/index.html"
status = 200Apache
We provide a detailed guide on how to configure Apache to handle dynamic routing and serve the correct template files for SEO purposes.
Nginx
For Nginx, a minimal configuration to handle basic SPA fallback looks like this:
nginx
location / {
try_files $uri /index.html;
}Troubleshooting
| Symptom | Fix |
|---|---|
| Refresh still 404s | Ensure rewrite file is at project root, not /public |
| Static assets break | Add an exception for /assets/ or generated file paths |
| API routes get redirected | Add rules before the SPA fallback |
| Changes not taking effect? | Restart your web server or clear your CDN cache. |
Support policy for self‑hosting
- WeWeb does not provide support for custom self‑hosting setups as part of standard plans.
- Because hosting environments vary widely (Vercel, Netlify, Cloudflare, NGINX, Apache, etc.), any issues related to hosting configuration, routing rules, or infrastructure must be handled by your hosting provider.
- We can only guarantee full support when deploying through WeWeb Hosting.
- For customers on an Enterprise plan, WeWeb can provide guidance and best‑effort assistance for self‑hosting deployments.

