Home Blog Work

Avoiding trailing slashes in URLs on Astro Vercel deployments

Published on March 7, 2023

After migrating my personal website from Next.js to Astro, I noticed that Google Search console reported duplicate content. After some research, I found out that the issue was caused by the way Astro handles trailing slashes in URLs.

Contrary to Next.js, Astro doesn’t automatically redirect URLs with trailing slashes to the same URL without trailing slashes. This is a problem because Google considers URLs with and without trailing slashes as different pages. This means that if you have a page at /about and another one at /about/, Google will consider them as two different pages.

Thankfully, I had equipped all my pages with a canonical link. The link always pointed to the page with the trailing slash. So Google Search console could alert me about the duplicate content. Otherwise, I would have never noticed the issue.

<link rel="canonical" href="https://noahflk.com/work/" />

Fixing the issue

The solution is to redirect all URLs with trailing slashes to the same URL without a trailing slash. This can be done with a simple redirect in the vercel.json config file in the project root.

{
  "trailingSlash": false,
}

Now all URLs with trailing slashes will be redirected to the same URL without trailing slashes. This will prevent Google from considering the two URLs as different pages.

To ensure that the sitemap generated by @astrojs/sitemap also contains the correct URLs, I set the trailingSlash option to 'never'.

export default defineConfig({
  trailingSlash: 'never',
});

And to ensure that all canonical links use URls without traling slashes, I changed the way I set canonical links to this:

---
function removeTrailingSlash(str: string) {
  return str.replace(/\/+$/, '');
}

const canonicalUrl = removeTrailingSlash(new URL(Astro.url.pathname, Astro.site).toString());
---

<link rel="canonical" href={canonicalUrl} />