From f15e5c89d0e550864390f9911eaf028e2021c105 Mon Sep 17 00:00:00 2001 From: Mastercuber Date: Tue, 24 Dec 2024 03:18:19 +0000 Subject: [PATCH] fix: doubly encoding of URLs (#390) --- .../server/sitemap/urlset/normalise.ts | 12 ++++++++- test/integration/single/urlEncoded.test.ts | 27 +++++++++++++++++++ 2 files changed, 38 insertions(+), 1 deletion(-) create mode 100644 test/integration/single/urlEncoded.test.ts diff --git a/src/runtime/server/sitemap/urlset/normalise.ts b/src/runtime/server/sitemap/urlset/normalise.ts index c0d92bd0..202e05a6 100644 --- a/src/runtime/server/sitemap/urlset/normalise.ts +++ b/src/runtime/server/sitemap/urlset/normalise.ts @@ -65,7 +65,7 @@ export function preNormalizeEntry(_e: SitemapUrl | string, resolvers?: NitroUrlR e.loc = e._relativeLoc } } - else { + else if (!isEncoded(e.loc)) { e.loc = encodeURI(e.loc) } if (e.loc === '') @@ -75,6 +75,16 @@ export function preNormalizeEntry(_e: SitemapUrl | string, resolvers?: NitroUrlR return e as ResolvedSitemapUrl } +export function isEncoded(url: string) { + // checks, if an url is already decoded + try { + return url !== decodeURIComponent(url) + } + catch { + return false + } +} + export function normaliseEntry(_e: ResolvedSitemapUrl, defaults: Omit, resolvers?: NitroUrlResolvers): ResolvedSitemapUrl { const e = defu(_e, defaults) as ResolvedSitemapUrl if (e.lastmod) { diff --git a/test/integration/single/urlEncoded.test.ts b/test/integration/single/urlEncoded.test.ts new file mode 100644 index 00000000..8c3aef4e --- /dev/null +++ b/test/integration/single/urlEncoded.test.ts @@ -0,0 +1,27 @@ +import { describe, expect, it } from 'vitest' +import { createResolver } from '@nuxt/kit' +import { $fetch, setup } from '@nuxt/test-utils' + +const { resolve } = createResolver(import.meta.url) + +await setup({ + rootDir: resolve('../../fixtures/basic'), + nuxtConfig: { + sitemap: { + urls: [ + '/Bücher', + '/Bibliothèque', + ], + }, + }, +}) +describe('query routes', () => { + it('should be url encoded', async () => { + const sitemap = await $fetch('/sitemap.xml') + + expect(sitemap).toContain('https://nuxtseo.com/B%C3%BCcher') + expect(sitemap).toContain('https://nuxtseo.com/Biblioth%C3%A8que') + expect(sitemap).not.toContain('https://nuxtseo.com/Bücher') + expect(sitemap).not.toContain('https://nuxtseo.com/Bibliothèque') + }, 60000) +})