Skip to content

Commit

Permalink
fix: filter i18n URLs based on non-prefixed path
Browse files Browse the repository at this point in the history
  • Loading branch information
harlan-zw committed Nov 13, 2023
1 parent da07f0d commit 94a5214
Show file tree
Hide file tree
Showing 3 changed files with 74 additions and 9 deletions.
4 changes: 2 additions & 2 deletions src/runtime/sitemap/builder/sitemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ export async function buildSitemap(sitemap: SitemapDefinition, resolvers: NitroU
).reverse()) as NitroRouteRules

// apply top-level path without prefix, users can still target the localed path
if (autoI18n?.locales && autoI18n?.strategy === 'no_prefix') {
if (autoI18n?.locales && autoI18n?.strategy !== 'no_prefix') {
// remove the locale path from the prefix, if it exists, need to use regex
const match = path.match(new RegExp(`^/(${autoI18n.locales.map(l => l.code).join('|')})(.*)`))
const pathWithoutPrefix = match?.[2]
Expand All @@ -117,7 +117,7 @@ export async function buildSitemap(sitemap: SitemapDefinition, resolvers: NitroU
enhancedUrls = applyI18nEnhancements(enhancedUrls, { isI18nMapped, autoI18n, sitemapName: sitemap.sitemapName })
// 3. filtered urls
// TODO make sure include and exclude start with baseURL?
const filteredUrls = filterSitemapUrls(enhancedUrls, sitemap)
const filteredUrls = filterSitemapUrls(enhancedUrls, { autoI18n, ...sitemap })
// 4. sort
const sortedUrls = maybeSort(filteredUrls)
// 5. maybe slice for chunked
Expand Down
28 changes: 21 additions & 7 deletions src/runtime/sitemap/urlset/filter.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { parseURL } from 'ufo'
import { createRouter, toRouteMatcher } from 'radix3'
import type { ResolvedSitemapUrl, SitemapDefinition } from '../../types'
import type { ModuleRuntimeConfig, ResolvedSitemapUrl, SitemapDefinition } from '../../types'

interface CreateFilterOptions {
include?: (string | RegExp)[]
Expand Down Expand Up @@ -40,15 +40,29 @@ function createFilter(options: CreateFilterOptions = {}): (path: string) => bool
}
}

export function filterSitemapUrls(_urls: ResolvedSitemapUrl[], filter: Pick<SitemapDefinition, 'sitemapName' | 'include' | 'exclude'>) {
export function filterSitemapUrls(_urls: ResolvedSitemapUrl[], options: Pick<ModuleRuntimeConfig, 'autoI18n'> & Pick<SitemapDefinition, 'sitemapName' | 'include' | 'exclude'>) {
// base may be wrong here
const urlFilter = createFilter(filter)
const urlFilter = createFilter(options)
return _urls.filter((e) => {
if (e._sitemap && filter.sitemapName)
return e._sitemap === filter.sitemapName
if (e._sitemap && options.sitemapName)
return e._sitemap === options.sitemapName
try {
const url = parseURL(e.loc)
return urlFilter(url.pathname)
const path = parseURL(e.loc).pathname
if (!urlFilter(path))
return false

const { autoI18n } = options
// if the non-prefixed locale is blocked then we block the prefixed versions
if (autoI18n?.locales && autoI18n?.strategy !== 'no_prefix') {
// remove the locale path from the prefix, if it exists, need to use regex
const match = path.match(new RegExp(`^/(${autoI18n.locales.map(l => l.code).join('|')})(.*)`))
const pathWithoutPrefix = match?.[2]
if (pathWithoutPrefix && pathWithoutPrefix !== path) {
if (!urlFilter(pathWithoutPrefix))
return false
}
}
return true
}
catch {
// invalid URL
Expand Down
51 changes: 51 additions & 0 deletions test/integration/i18n/filtering.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
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/i18n'),
nuxtConfig: {
sitemap: {
sitemaps: {
foo: {
urls: [
// custom blocked routes
'/admin',
'/es/admin',
'/fr/admin',
'/admin/foo',
'/es/admin/foo',
'/fr/admin/foo',
'/admin/foo/bar',
'/es/admin/foo/bar',
'/fr/admin/foo/bar',
// should be only route
'/valid',
],
exclude: [
'/admin/**',
],
},
},
},
},
})
describe('multi filtering', () => {
it('basic', async () => {
let sitemap = await $fetch('/foo-sitemap.xml')

// strip lastmod
sitemap = sitemap.replace(/<lastmod>.*<\/lastmod>/g, '')

expect(sitemap).toMatchInlineSnapshot(`
"<?xml version=\\"1.0\\" encoding=\\"UTF-8\\"?><?xml-stylesheet type=\\"text/xsl\\" href=\\"/__sitemap__/style.xsl\\"?>
<urlset xmlns:xsi=\\"http://www.w3.org/2001/XMLSchema-instance\\" xmlns:video=\\"http://www.google.com/schemas/sitemap-video/1.1\\" xmlns:xhtml=\\"http://www.w3.org/1999/xhtml\\" xmlns:image=\\"http://www.google.com/schemas/sitemap-image/1.1\\" xmlns:news=\\"http://www.google.com/schemas/sitemap-news/0.9\\" xsi:schemaLocation=\\"http://www.sitemaps.org/schemas/sitemap/0.9 http://www.sitemaps.org/schemas/sitemap/0.9/sitemap.xsd http://www.google.com/schemas/sitemap-image/1.1 http://www.google.com/schemas/sitemap-image/1.1/sitemap-image.xsd\\" xmlns=\\"http://www.sitemaps.org/schemas/sitemap/0.9\\">
<url>
<loc>https://nuxtseo.com/valid</loc>
</url>
</urlset>"
`)
}, 60000)
})

0 comments on commit 94a5214

Please sign in to comment.