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) +})