Nuxt 3 - how to remove trailing slash?
Asked Answered
O

5

6

In Nuxt 3, how to remove trailing slash from urls?

In Nuxt 2, it was done by adding these lines to nuxt.config.js:

router: {
    trailingSlash: false
  }

What is the equivalent in Nuxt 3?

Overtrump answered 31/10, 2022 at 9:28 Comment(0)
T
4

According to the nuxt docs, and vue router docs. It seems that trailingSlash has been replaced by strict which controls "Whether to disallow a trailing slash or not.".

However, according to the docs, the default value is false, meaning that without any configuration you should be able to visit pages both with and without trailing slash.

Trauma answered 31/10, 2022 at 13:20 Comment(3)
Just to make it easier for anyone, the replacement code in nuxt.config is {router:{options:{strict: true}}}Overtrump
This does not do anything basically. Your routes are just not going to render on a trailing slash request. So you can still visit /page/ it will just display empty. Check github.com/nuxt/nuxt/issues/15462#issuecomment-1407374859Ninfaningal
For the sake of clarity: this option is for when you want to disable trailing slashes completely (and trigger a 404 not found for URLs with a trailing slash), not for redirecting from an URL with trailing slash to one without.Orangeade
R
8

Based on @evg_ny's answer, I created this version which will work with Nuxt3 to redirect routes with the trailing slash to the non-trailing slash variant:

export default defineNuxtRouteMiddleware((to, from) => {
  if (to.path !== '/' && to.path.endsWith('/')) {
    const { path, query, hash } = to;
    const nextPath = path.replace(/\/+$/, '') || '/';
    const nextRoute = { path: nextPath, query, hash };
    return navigateTo(nextRoute, { redirectCode: 301 });
  }
})

Save it in ./middleware/redirect-trailing-slash.global.js and it'll work globally

Roethke answered 29/11, 2022 at 22:28 Comment(4)
Thanks, I mentioned it in github.com/nuxt/nuxt/issues/15462#issuecomment-1407374859Ninfaningal
Awesome. I wish Nuxt shipped with a bunch of default middleware like LaravelGruchot
This works correctly, and is the right way to redirect an URL with trailing slash to an URL without it.Orangeade
This creates an infinite redirect if you refresh the page.Gangboard
T
4

According to the nuxt docs, and vue router docs. It seems that trailingSlash has been replaced by strict which controls "Whether to disallow a trailing slash or not.".

However, according to the docs, the default value is false, meaning that without any configuration you should be able to visit pages both with and without trailing slash.

Trauma answered 31/10, 2022 at 13:20 Comment(3)
Just to make it easier for anyone, the replacement code in nuxt.config is {router:{options:{strict: true}}}Overtrump
This does not do anything basically. Your routes are just not going to render on a trailing slash request. So you can still visit /page/ it will just display empty. Check github.com/nuxt/nuxt/issues/15462#issuecomment-1407374859Ninfaningal
For the sake of clarity: this option is for when you want to disable trailing slashes completely (and trigger a 404 not found for URLs with a trailing slash), not for redirecting from an URL with trailing slash to one without.Orangeade
P
2

If your goal is to remove all trailing slashes and redirect to the page without trailing slashes then you can use middleware like this:

export default function ({ route, redirect }) {
  if (route.path !== '/' && route.path.endsWith('/')) {
    const { path, query, hash } = route;
    const nextPath = path.replace(/\/+$/, '') || '/';
    const nextRoute = { path: nextPath, query, hash };

    return navigateTo(nextRoute, { redirectCode: 301 });
  }
}
Phylis answered 31/10, 2022 at 15:12 Comment(0)
B
1

For Nuxt 3 using SSR, the directory does exist and Apache is supposed to serve that directory's physical index.html file. This is different than the client-side rendering which works by serving the root index.html for everything.

The solution is to 1) turn off directory trailing slash, and then 2) rewrite the request to request that directory's index.html file.

My .htaccess w/ before and after:

# BEFORE
#RewriteEngine On
#RewriteBase /
#RewriteRule ^index\.html$ - [L]
#RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d
#RewriteRule . /index.html [L] # For non-SSR, serve the root index.html


# AFTER, WITH SSR
DirectorySlash Off # Turn off trailing slash

RewriteEngine On
RewriteBase /
RewriteRule ^index\.html$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
#RewriteCond %{REQUEST_FILENAME} !-d # Omit for SSR because there is a physical directory
RewriteRule ^(.*)$ $1/index.html [L]
#RewriteRule . /index.html [L] # Omit for SSR because the served file is the requested dir's index.html (rather than the root index.html)
Brinker answered 21/12, 2023 at 18:30 Comment(1)
This has been my challenge for a long time. I appreciate your contribution.Feil
T
1

I noticed the middleware solution contains a security risk. If you run the server, a url like https://mynuxtproject.com//evil.example.com/ could redirect to a third party site, because you'll try to redirect to //evil.example.com.

Trove answered 1/2 at 13:30 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.