How to remove trailing slash from url in nuxt.js?

I am looking for a way to redirect all my URLs so that they all do not have a slash in the end. I have tried with https://www.npmjs.com/package/@nuxtjs/redirect-module, but it does not redirect correctly.

redirect: [
    {
      from: '\/$',
      to: (from, req) => req.url.replace(/\/$/, '')
    }
  ],

For example, to change such a url http://localhost:8080/item/test-slug/ This module redirects me to http://localhost:8080/item/test-slug/item/test-slug

Any insight will be welcome. Thanks!

Upvotes: 7

Views: 17698

Answers (6)

Dominio
Dominio

Reputation: 16

For those who are having problem with the top answer (creating custom middleware to redirect) using Nuxt 2.15.8. If you are getting the too many redirects error, it may be caused by Nuxt doing its own internal redirection to end-slash variant (from test-slug to test-slug/). Nuxt decides to add a slash when you have the same name folder in the static folder as you page filename.

The solution is renaming either of those.

Upvotes: 0

Korvent
Korvent

Reputation: 58

For those who are looking for a solution working on Nuxt 3, you have to use a middleware.

Create a file named trailingSlash.global.js in the middleware directory and copy/paste this inside :

export default defineNuxtRouteMiddleware((to) => {
  if (to.path.slice(-1) === '/') {
    return navigateTo({...to,
      path: to.path.slice(0, -1)
    })
  }
});

Upvotes: 1

Michael
Michael

Reputation: 1089

In nuxt.config.js as @Hardik Shah and @tsnkff says

router: {
  trailingSlash: false
},

For other needs use ufo package https://github.com/unjs/ufo#withouttrailingslash

withoutTrailingSlash Ensures url does not ends with a trailing slash

// Result: /foo
withoutTrailingSlash('/foo/')
// Result: /path?query=true
withoutTrailingSlash('/path/?query=true', true)

withTrailingSlash Ensures url ends with a trailing slash

// Result: /foo/
withTrailingSlash('/foo')
// Result: /path/?query=true
withTrailingSlash('/path?query=true', true)

and other helpful functions are in unjs/ufo package that created by nuxt team and is used in nuxt code also.

Upvotes: 0

Nelmad
Nelmad

Reputation: 169

I've solved this problem using custom middleware. It redirects to url which don't have a slash in the end.

Create src/middleware/trailingSlashRedirect.js

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 };

    redirect(nextRoute);
  }
}

Register it in nuxt.config.js:

export default {
  ...
  router: {
    middleware: 'trailingSlashRedirect',
  },
}

So you should not use any module to solve this problem. I think it's much better than using third party libs.

Upvotes: 16

Hardik Shah
Hardik Shah

Reputation: 1456

You can remove trailing slash with Nuxt latest version(Available since v2.10) with below way: https://nuxtjs.org/api/configuration-router/#trailingslash

trailingSlash : Type: Boolean or undefined
Default: undefined
Available since: v2.10
ex:
router: {
  trailingSlash: false
}

Or with the older version of Nuxt You can use nuxt-trailingslash-module https://www.npmjs.com/package/nuxt-trailingslash-module

npm i nuxt-trailingslash-module

Upvotes: 5

tsnkff
tsnkff

Reputation: 806

So the only solution I found so far isn't perfect.

Using the redirect-module , I added the following at the top of my redirects list:

{
  // eslint-disable-next-line
  from: '(?!^\/$|^\/[?].*$)(.*\/[?](.*)$|.*\/$)',
  to: (from, req) => {
    const base = req._parsedUrl.pathname.replace(/\/$/, '');
    const search = req._parsedUrl.search;
    return base + (search != null ? search : '');
  }
},

Also in nuxt.config.js I made sure to add the trailing slash configuration. (See the doc)

router: {
  trailingSlash: false
},

Note: It redirect all URLS ending with '/' with query parameters, but it doesn't match the home page '/' (which seems to be handled somehow)

The following will redirect the following:

  • '/blog/' to '/blog'
  • '/blog/?a=b' to '/blog?a=b'
  • '/blog/foo/' to '/blog/foo'
  • '/blog/foo/?a=b' to '/blog/foo?a=b'
  • '/' to '/'. --> won't work
  • '/?a=b' to '/?a=b'. --> won't work

I made a test list available here


Explanation of the regex

It might not be perfect since I'm not a Regex expert but:

'(?!^\/$|^\/[?].*$)(.*\/[?](.*)$|.*\/$)'

It's broken it 2 pieces: 1 exclusion, and 1 inclusion.

The exclusion: (?!^\/$|^\/[?].*$), consist of a check to exclude standalone trailing comma (/) or standalone trailing comma with query string /?foo=bar routes. It's used mainly for the home page.

The inclusion: (.*\/[?](.*)$|.*\/$), consists of checking for the trialing comma (/blog/) or a trailing comma with query string (/blog/?foo=bar)

Upvotes: 2

Related Questions