I'm doing the following:
- Production Build: npm run generate
- I copy the dist
folder into the Tomcat Webapps, and it works fine
- Whenever I refresh a dynamic route, it shows 404
URLs that work:
https://ip:port/entryPath/dashboard/user
URLs that don't work:
https://ip:port/entryPath/dashboard/user/123
https://ip:port/entryPath/dashboard/user/123/settings
https://ip:port/entryPath/dashboard/user/123/privacy
I want to be able to share an URL such as:
https://ip:port/entryPath/dashboard/user/123/activity
So other users just clicking the URL should be directly able to access it. But it just ends up with a 404, no matter where I deploy.
Please Note:
My intention is to deploy the dist
folder contents on Tomcat webapps folder.
When your app is running as a single page app (SPA), everything is happening within that original entry page - you are not actually loading a new page when you navigate between routes. As long as you don't refresh the page, it doesn't matter whether or not those routes correspond to actual html files on the server because your SPA knows what do. However, if you reload the page or enter from a dynamic route, if there's no html file at that URL, a static server will serve a 404 because it doesn't know what else to do.
You might understand all of that already since you're running generate
to build out static pages. But Nuxt's generate
command only knows to generate pages for the *.vue
files in your pages
directory. Dynamic routes are ignored. Check your dist
folder that you uploaded - there should be a corresponding path for each of your working URLs (which correspond to your pages
directory), but you won't find files for your dynamic routes.
To solve this, you need to give an array of dynamic routes to the generate
command. You can do that by adding something like this to nuxt.config.js
:
generate: {
// create an array of all routes for generating static pages
// careful, this is only used by `npm run generate`. These must match SPA mode routes
routes: function () {
return axios.get(
'https://jsonplaceholder.typicode.com/users'
)
.then((response) => {
let users = response.data.map((user) => {
return {
route: '/users/' + user.id,
payload: user
}
});
return ['/some-other-dynamic-route-or-array-of-routes/', ...users]
});
}
}
Here's a nice article about static sites with Nuxt with examples
You'll know your pages are being generated as expected if you see them in your dist
directory.
Obviously for something like your user pages, this approach means that new users pages created after your build will not exist until your next build. You could try using the SPA fallback to load the SPA for unmatched routes.
Edit: You could also use hash mode. So instead of https://ip:port/entryPath/dashboard/user/123
your URL would be https://ip:port/entryPath#dashboard/user/123
. In this case, the server is always requesting your root SPA index.html, which will use the route to determine what to do (so it should perform as it does now when you navigate to that route). If you do it this way, you will just be using SPA mode and don't need to generate any of your pages at all. This is not good for SEO, but you will have shareable URLs that work right away.
You should setup your server to always request your spa's index.html for all routes that are not a file.
.htaccess
<ifModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule (.*) index.html [QSA,L]
</ifModule>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With