### Clone and Install Super Sitemap Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Use these commands to clone the repository and install dependencies locally for development. ```bash git clone https://github.com/jasongitmail/super-sitemap.git bun install # Then edit files in /src/lib ``` -------------------------------- ### Static robots.txt Configuration Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Create a static /static/robots.txt file to guide search engine crawlers. This is a simple and common approach. ```text User-agent: * Allow: / Sitemap: https://example.com/sitemap.xml ``` -------------------------------- ### Example Sitemap XML Output Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md An example of a sitemap XML file generated with various URL entries, including static pages and dynamic routes. ```xml https://example/ daily 0.7 https://example/about daily 0.7 https://example/blog daily 0.7 https://example/login daily 0.7 https://example/pricing daily 0.7 https://example/privacy daily 0.7 https://example/signup daily 0.7 https://example/support daily 0.7 https://example/terms daily 0.7 https://example/blog/hello-world daily 0.7 https://example/blog/another-post daily 0.7 https://example/blog/tag/red daily 0.7 https://example/blog/tag/green daily 0.7 https://example/blog/tag/blue daily 0.7 https://example/campsites/usa/new-york daily 0.7 https://example/campsites/usa/california daily 0.7 https://example/campsites/canada/toronto daily 0.7 https://example/foo.pdf daily 0.7 ``` -------------------------------- ### Configure Param Values for Routes Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Example of how to configure parameter values for dynamic routes, including optional parameters and metadata like `lastmod`, `changefreq`, and `priority`. ```typescript paramValues: { '/blog/[slug]': ['hello-world', 'another-post'] '/campsites/[country]/[state]': [ ['usa', 'colorado'], ['canada', 'toronto'] ], '/athlete-rankings/[country]/[state]': [ { values: ['usa', 'new-york'], // required lastmod: '2025-01-01T00:00:00Z', // optional changefreq: 'daily', // optional priority: 0.5, // optional }, { values: ['usa', 'california'], lastmod: '2025-01-01T01:16:52Z', changefreq: 'daily', priority: 0.5, }, ], } ``` -------------------------------- ### Generated Sitemap XML with hreflang Attributes Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Example of sitemap.xml output demonstrating how Super Sitemap includes alternate language links (hreflang) for each URL, facilitating SEO for multi-language sites. ```xml ... https://example.com/about https://example.com/de/about https://example.com/zh/about ... ``` -------------------------------- ### Sitemap Index XML Structure Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md This is an example of the XML structure for a sitemap index, which contains links to paginated sitemaps. ```xml https://example.com/sitemap1.xml https://example.com/sitemap2.xml https://example.com/sitemap3.xml ``` -------------------------------- ### Get Sampled URLs from Sitemap Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Use sampledUrls to get a list of unique URLs from a sitemap.xml file. This is useful for testing and SEO analysis. ```javascript import { sampledUrls } from 'super-sitemap'; const urls = await sampledUrls('http://localhost:5173/sitemap.xml'); // [ // 'http://localhost:5173/', // 'http://localhost:5173/about', // 'http://localhost:5173/pricing', // 'http://localhost:5173/features', // 'http://localhost:5173/login', // 'http://localhost:5173/signup', // 'http://localhost:5173/blog', // 'http://localhost:5173/blog/hello-world', // 'http://localhost:5173/blog/tag/red', // ] ``` -------------------------------- ### Generate Sitemap with Parameterized Routes (TypeScript) Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md This TypeScript version of the sitemap generation handles parameterized routes similarly to the JavaScript example. It includes type definitions for better code safety and maintainability. Ensure data fetching logic is correctly implemented. ```typescript // /src/routes/sitemap.xml/+server.ts import type { RequestHandler } from '@sveltejs/kit'; import * as sitemap from 'super-sitemap'; import * as blog from '$lib/data/blog'; export const prerender = true; // optional export const GET: RequestHandler = async () => { // Get data for parameterized routes however you need to; this is only an example. let blogSlugs, blogTags; try { [blogSlugs, blogTags] = await Promise.all([blog.getSlugs(), blog.getTags()]); } catch (err) { throw error(500, 'Could not load data for param values.'); } return await sitemap.response({ origin: 'https://example.com', excludeRoutePatterns: [ '^/dashboard.*', // i.e. routes starting with `/dashboard` '.*\[page=integer\].*', // i.e. routes containing `[page=integer]`–e.g. `/blog/2` '.*\(authenticated\).*', // i.e. routes within a group ], paramValues: { // paramValues can be a 1D array of strings '/blog/[slug]': blogSlugs, // e.g. ['hello-world', 'another-post'] '/blog/tag/[tag]': blogTags, // e.g. ['red', 'green', 'blue'] // Or a 2D array of strings '/campsites/[country]/[state]': [ ['usa', 'new-york'], ['usa', 'california'], ['canada', 'toronto'], ], // Or an array of ParamValue objects '/athlete-rankings/[country]/[state]': [ { values: ['usa', 'new-york'], // required lastmod: '2025-01-01T00:00:00Z', // optional changefreq: 'daily', // optional priority: 0.5, // optional }, { values: ['usa', 'california'], lastmod: '2025-01-01T00:00:00Z', changefreq: 'daily', priority: 0.5, }, ], }, headers: { 'custom-header': 'foo', // case insensitive; xml content type & 1h CDN cache by default }, additionalPaths: [ '/foo.pdf', // for example, to a file in your static dir ], defaultChangefreq: 'daily', defaultPriority: 0.7, sort: 'alpha', // default is false; 'alpha' sorts all paths alphabetically. processPaths: (paths: sitemap.PathObj[]) => { // Optional callback to allow arbitrary processing of your path objects. See the // processPaths() section of the README. return paths; }, }); }; ``` -------------------------------- ### Add Trailing Slashes with processPaths Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Demonstrates using `processPaths` to append a trailing slash to all generated URLs. This example also shows how to handle alternates for i18n. Note that this is generally not recommended. ```typescript return await sitemap.response({ // ... processPaths: (paths: sitemap.PathObj[]) => { // Add trailing slashes to all paths. (This is just an example and not // actually recommended. Using SvelteKit's default of no trailing slash is // preferable because it provides consistency among all possible paths, // even files like `/foo.pdf`.) return paths.map(({ path, alternates, ...rest }) => { const rtrn = { path: path === '/' ? path : `${path}/`, ...rest }; if (alternates) { rtrn.alternates = alternates.map((alternate: sitemap.Alternate) => ({ ...alternate, path: alternate.path === '/' ? alternate.path : `${alternate.path}/`, })); } return rtrn; }); }, }); ``` -------------------------------- ### Get Sampled Paths from Sitemap Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Use sampledPaths to retrieve a list of unique paths from a sitemap.xml. This utility is designed for testing purposes. ```javascript import { sampledPaths } from 'super-sitemap'; const urls = await sampledPaths('http://localhost:5173/sitemap.xml'); // [ // '/about', // '/pricing', // '/features', // '/login', // '/signup', // '/blog', // '/blog/hello-world', // '/blog/tag/red', // ] ``` -------------------------------- ### Static robots.txt Configuration Source: https://context7.com/jasongitmail/super-sitemap/llms.txt A simple static robots.txt file that allows all access and references the sitemap XML file. ```text # /static/robots.txt (simplest — static file) User-agent: * Allow: / Sitemap: https://example.com/sitemap.xml ``` -------------------------------- ### Dynamic robots.txt with SvelteKit Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Configure a dynamic robots.txt at /src/routes/robots.txt/+server.ts using SvelteKit. This allows for dynamic sitemap URL inclusion based on environment variables. ```typescript import * as env from '$env/static/public'; export const prerender = true; export async function GET(): Promise { // prettier-ignore const body = [ 'User-agent: *', 'Allow: /', '', `Sitemap: ${env.PUBLIC_ORIGIN}/sitemap.xml` ].join('\n').trim(); const headers = { 'Content-Type': 'text/plain', }; return new Response(body, { headers }); } ``` -------------------------------- ### Basic Sitemap Generation (JavaScript) Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Generates a basic sitemap using the super-sitemap library in a SvelteKit +server.js file. Ensure the route file is named 'sitemap.xml.js' or 'sitemap.xml/+server.js'. ```javascript // /src/routes/sitemap.xml/+server.js import * as sitemap from 'super-sitemap'; export const GET = async () => { return await sitemap.response({ origin: 'https://example.com', }); }; ``` -------------------------------- ### Basic Sitemap Generation (TypeScript) Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Generates a basic sitemap using the super-sitemap library in a SvelteKit +server.ts file. Ensure the route file is named 'sitemap.xml.ts' or 'sitemap.xml/+server.ts'. ```typescript // /src/routes/sitemap.xml/+server.ts import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = async () => { return await sitemap.response({ origin: 'https://example.com', }); }; ``` -------------------------------- ### sitemap.response(config) Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Generates the XML sitemap response. This function discovers routes, expands parameterized routes, applies exclusion patterns, and returns a standard SvelteKit `Response` object with XML content and default caching headers. It ensures all parameterized routes are explicitly handled to prevent omissions. ```APIDOC ## GET /sitemap.xml ### Description Generates an XML sitemap for the SvelteKit application. It discovers all routes, handles parameterized routes with provided values, and applies exclusion patterns to generate a compliant sitemap. ### Method GET ### Endpoint /sitemap.xml ### Parameters #### Query Parameters None #### Request Body None ### Configuration Object (`config`) - **origin** (string) - Required - The base URL of the website (e.g., 'https://example.com'). Must not have a trailing slash. - **excludeRoutePatterns** (string[]) - Optional - An array of regular expressions to exclude specific routes from the sitemap. - **paramValues** (object) - Optional - An object mapping route patterns to their parameter values. For parameterized routes (e.g., `/blog/[slug]`), this provides the values to generate URLs. Can be a 1D array of strings, a 2D array of string arrays, or an array of objects with `values`, `lastmod`, `changefreq`, and `priority` properties for per-path metadata. - **additionalPaths** (string[]) - Optional - An array of additional paths to include in the sitemap, typically for files in the `/static` directory that are not discoverable via routes. - **headers** (object) - Optional - An object to override default HTTP headers, such as `cache-control`. - **defaultChangefreq** (string) - Optional - The default `changefreq` value for all URLs if not specified otherwise (e.g., 'daily'). - **defaultPriority** (number) - Optional - The default `priority` value for all URLs if not specified otherwise (e.g., 0.7). - **sort** ('alpha' | false) - Optional - Determines the sorting order of URLs. Set to 'alpha' for alphabetical sorting or `false` for no sorting (default). ### Request Example ```ts // src/routes/sitemap.xml/+server.ts import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; import { error } from '@sveltejs/kit'; import * as blog from '$lib/data/blog'; export const GET: RequestHandler = async () => { let slugs: string[], tags: string[]; try { [slugs, tags] = await Promise.all([blog.getSlugs(), blog.getTags()]); } catch (err) { throw error(500, 'Could not load data for param values.'); } return await sitemap.response({ origin: 'https://example.com', excludeRoutePatterns: [ '^/dashboard.*', '.*\[page=integer\].*', '.*\(authenticated\).*', ], paramValues: { '/blog/[slug]': slugs, '/blog/tag/[tag]': tags, '/campsites/[country]/[state]': [ ['usa', 'new-york'], ['usa', 'california'], ['canada', 'toronto'], ], '/athlete-rankings/[country]/[state]': [ { values: ['usa', 'new-york'], lastmod: '2025-01-01T00:00:00Z', changefreq: 'daily', priority: 0.5, }, { values: ['usa', 'california'], lastmod: '2025-01-05T00:00:00Z', changefreq: 'weekly', priority: 0.4, }, ], }, additionalPaths: ['/foo.pdf'], headers: { 'cache-control': 'max-age=0, s-maxage=600', }, defaultChangefreq: 'daily', defaultPriority: 0.7, sort: 'alpha', }); }; ``` ### Response #### Success Response (200) - **Content-Type**: application/xml - **Cache-Control**: (default: `max-age=3600, s-maxage=3600` or as overridden by `headers`) An XML document conforming to the sitemaps.org protocol. #### Response Example ```xml https://example.com/ daily 0.7 https://example.com/about daily 0.7 https://example.com/blog/hello-world daily 0.7 ... ``` ``` -------------------------------- ### Dynamic robots.txt Generation in SvelteKit Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Dynamically generates robots.txt using environment variables for the sitemap URL. Ensure `PUBLIC_ORIGIN` is set in your .env file. ```typescript // /src/routes/robots.txt/+server.ts import * as env from '$env/static/public'; export const prerender = true; export async function GET(): Promise { const body = [ 'User-agent: *', 'Allow: /', '', `Sitemap: ${env.PUBLIC_ORIGIN}/sitemap.xml`, ].join('\n'); return new Response(body, { headers: { 'Content-Type': 'text/plain' }, }); } ``` -------------------------------- ### Enable Sitemap Index Support (JavaScript) Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Rename your route to `sitemap[[page]].xml` and pass the page param via your sitemap config. This is necessary for sitemap index support when you have >=50,000 URLs. ```javascript // /src/routes/sitemap[[page]].xml/+server.js import * as sitemap from 'super-sitemap'; export const GET = async ({ params }) => { return await sitemap.response({ origin: 'https://example.com', page: params.page, // maxPerPage: 45_000 // optional; defaults to 50_000 }); }; ``` -------------------------------- ### Enable Sitemap Index Support (TypeScript) Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Rename your route to `sitemap[[page]].xml` and pass the page param via your sitemap config. This is necessary for sitemap index support when you have >=50,000 URLs. ```typescript // /src/routes/sitemap[[page]].xml/+server.ts import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = async ({ params }) => { return await sitemap.response({ origin: 'https://example.com', page: params.page, // maxPerPage: 45_000 // optional; defaults to 50_000 }); }; ``` -------------------------------- ### Generate Sitemap with Parameterized Routes (JavaScript) Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Use this snippet to generate a sitemap with dynamic routes. It handles parameterized routes by providing values for slugs and tags, and allows exclusion of specific route patterns. Ensure necessary data fetching functions are implemented. ```javascript // /src/routes/sitemap.xml/+server.js import * as sitemap from 'super-sitemap'; import * as blog from '$lib/data/blog'; export const prerender = true; // optional export const GET = async () => { // Get data for parameterized routes however you need to; this is only an example. let blogSlugs, blogTags; try { [blogSlugs, blogTags] = await Promise.all([blog.getSlugs(), blog.getTags()]); } catch (err) { throw error(500, 'Could not load data for param values.'); } return await sitemap.response({ origin: 'https://example.com', excludeRoutePatterns: [ '^/dashboard.*', // i.e. routes starting with `/dashboard` '.*\[page=integer\].*', // i.e. routes containing `[page=integer]`–e.g. `/blog/2` '.*\(authenticated\).*', // i.e. routes within a group ], paramValues: { // paramValues can be a 1D array of strings '/blog/[slug]': blogSlugs, // e.g. ['hello-world', 'another-post'] '/blog/tag/[tag]': blogTags, // e.g. ['red', 'green', 'blue'] // Or a 2D array of strings '/campsites/[country]/[state]': [ ['usa', 'new-york'], ['usa', 'california'], ['canada', 'toronto'], ], // Or an array of ParamValue objects '/athlete-rankings/[country]/[state]': [ { values: ['usa', 'new-york'], // required lastmod: '2025-01-01T00:00:00Z', // optional changefreq: 'daily', // optional priority: 0.5, // optional }, { values: ['usa', 'california'], lastmod: '2025-01-01T00:00:00Z', changefreq: 'daily', priority: 0.5, }, ], }, headers: { 'custom-header': 'foo', // case insensitive; xml content type & 1h CDN cache by default }, additionalPaths: [ '/foo.pdf', // for example, to a file in your static dir ], defaultChangefreq: 'daily', defaultPriority: 0.7, sort: 'alpha', // default is false; 'alpha' sorts all paths alphabetically. processPaths: (paths) => { // Optional callback to allow arbitrary processing of your path objects. See the // processPaths() section of the README. return paths; }, }); }; ``` -------------------------------- ### Generate XML Sitemap Response with Super Sitemap Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Use this function in a SvelteKit server route to generate an XML sitemap. Configure origin, exclude patterns, parameter values for dynamic routes, additional paths, and custom headers. Ensure all parameterized routes are handled to prevent omissions. ```typescript import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; import { error } from '@sveltejs/kit'; import * as blog from '$lib/data/blog'; export const GET: RequestHandler = async () => { let slugs: string[], tags: string[]; try { [slugs, tags] = await Promise.all([blog.getSlugs(), blog.getTags()]); // slugs => ['hello-world', 'another-post'] // tags => ['red', 'green', 'blue'] } catch (err) { throw error(500, 'Could not load data for param values.'); } return await sitemap.response({ origin: 'https://example.com', // required; no trailing slash excludeRoutePatterns: [ '^/dashboard.*', // exclude all dashboard routes '.*\[page=integer\].*', // exclude paginated routes like /blog/2 '.*\(authenticated\).*', // exclude routes inside a route group ], paramValues: { '/blog/[slug]': slugs, // 1D array of strings '/blog/tag/[tag]': tags, '/campsites/[country]/[state]': [ // 2D array for multi-param routes ['usa', 'new-york'], ['usa', 'california'], ['canada', 'toronto'], ], '/athlete-rankings/[country]/[state]': [ // ParamValue[] for per-path metadata { values: ['usa', 'new-york'], lastmod: '2025-01-01T00:00:00Z', changefreq: 'daily', priority: 0.5, }, { values: ['usa', 'california'], lastmod: '2025-01-05T00:00:00Z', changefreq: 'weekly', priority: 0.4, }, ], }, additionalPaths: ['/foo.pdf'], // files in /static not discoverable via routes headers: { 'cache-control': 'max-age=0, s-maxage=600', // override default 1h CDN cache }, defaultChangefreq: 'daily', // applied to every URL that doesn't specify one defaultPriority: 0.7, // applied to every URL that doesn't specify one sort: 'alpha', // 'alpha' | false (default) }); }; /* * Output: HTTP 200 with Content-Type: application/xml * * * * * https://example.com/ * daily * 0.7 * * * https://example.com/about * daily * 0.7 * * * https://example.com/blog/hello-world * daily * 0.7 * * ... * */ ``` -------------------------------- ### Query SQL for Dynamic Route Params Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Use these SQL queries to fetch values for dynamic route segments. Ensure to use DISTINCT for routes listing multiple items and consider LOWER casing for case-insensitive matching. ```SQL -- Route: /blog/[slug] SELECT slug FROM blog_posts WHERE status = 'published'; ``` ```SQL -- Route: /blog/category/[category] SELECT DISTINCT LOWER(category) FROM blog_posts WHERE status = 'published'; ``` ```SQL -- Route: /campsites/[country]/[state] SELECT DISTINCT LOWER(country), LOWER(state) FROM campsites; ``` ```SQL -- Obviously, remember to escape your `params.slug` values to prevent SQL injection. SELECT * FROM campsites WHERE LOWER(country) = LOWER(params.country) AND LOWER(state) = LOWER(params.state) LIMIT 10; ``` -------------------------------- ### Sample URLs for Testing with `sampledUrls` and `sampledPaths` Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Fetch one URL per route pattern from a generated sitemap for testing purposes. `sampledUrls` returns full URLs, while `sampledPaths` returns only the path strings. Handles sitemap indexes transparently. Useful for Playwright tests to avoid redundant sitemap configuration. ```typescript // src/tests/sitemap.test.ts import { expect, test } from '@playwright/test'; import { sampledUrls, sampledPaths } from 'super-sitemap'; let sampledPublicUrls: string[] = []; let sampledPublicPaths: string[] = []; try { // sampledUrls: full URLs, one per unique route sampledPublicUrls = await sampledUrls('http://localhost:4173/sitemap.xml'); // => [ // 'http://localhost:4173/', // 'http://localhost:4173/about', // 'http://localhost:4173/pricing', // 'http://localhost:4173/blog', // 'http://localhost:4173/blog/hello-world', // one sample for /blog/[slug] // 'http://localhost:4173/blog/tag/red', // one sample for /blog/tag/[tag] // ] // sampledPaths: path-only variant sampledPublicPaths = await sampledPaths('http://localhost:4173/sitemap.xml'); // => ['/', '/about', '/pricing', '/blog', '/blog/hello-world', '/blog/tag/red'] } catch (err) { console.error('Could not load sampled URLs:', err); } // Use in a Playwright test to smoke-test all public routes test('all public pages return HTTP 200', async ({ page }) => { for (const url of sampledPublicUrls) { const response = await page.goto(url); expect(response?.status(), `Failed for ${url}`).toBe(200); } }); test('/sitemap.xml is valid XML with enough entries', async ({ page }) => { const response = await page.goto('/sitemap.xml'); expect(response?.status()).toBe(200); const urls = await page.$$eval('url', (nodes) => nodes.map((n) => ({ loc: n.querySelector('loc')?.textContent })) ); expect(urls.length).toBeGreaterThan(5); for (const { loc } of urls) { expect(loc).toBeTruthy(); expect(() => new URL(loc!)).not.toThrow(); } }); ``` -------------------------------- ### Map Dynamic Routes with Language Parameters Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Update the `paramValues` configuration to include language slugs for dynamic routes that have been moved into language-specific directories. ```javascript paramValues: { '/[[lang]]/blog/[slug]': ['hello-world', 'post-2'], // was '/blog/[slug]' '/[[lang]]/campsites/[country]/[state]': [ ['usa', 'new-york'], ['canada', 'toronto'], ], } ``` -------------------------------- ### Super Sitemap TypeScript Types Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Demonstrates the structure and usage of ParamValue, PathObj, and SitemapConfig types for defining sitemap metadata, individual paths, and overall configuration. ```typescript import type { SitemapConfig, PathObj, ParamValues, ParamValue, Alternate, Changefreq, Priority } from 'super-sitemap'; // ParamValue — per-path metadata for a single parameterized URL const campsite: ParamValue = { values: ['usa', 'new-york'], // required; maps to route params in order lastmod: '2025-06-01T00:00:00Z', // optional; ISO 8601 changefreq: 'weekly', // optional; 'always'|'hourly'|'daily'|'weekly'|'monthly'|'yearly'|'never' priority: 0.6, // optional; 0.0 – 1.0 in 0.1 increments }; // PathObj — shape of each item in the processPaths() callback const pathObj: PathObj = { path: '/blog/hello-world', lastmod: '2025-06-01T00:00:00Z', changefreq: 'daily', priority: 0.7, alternates: [ // present when lang config is used { lang: 'en', path: '/blog/hello-world' }, { lang: 'zh', path: '/zh/blog/hello-world' }, ], }; // SitemapConfig — full config passed to sitemap.response() const config: SitemapConfig = { origin: 'https://example.com', // required excludeRoutePatterns: [], // optional regex strings paramValues: {}, // optional; Record additionalPaths: [], // optional; paths not in /src/routes headers: {}, // optional; merged case-insensitively defaultChangefreq: 'daily', // optional defaultPriority: 0.7, // optional sort: 'alpha', // optional; 'alpha' | false maxPerPage: 50_000, // optional; triggers sitemap index above this page: undefined, // optional; pass params.page for sitemap index support lang: { default: 'en', alternates: ['zh'] }, // optional processPaths: (paths) => paths, // optional; synchronous callback }; ``` -------------------------------- ### Automatic Sitemap Pagination with Super Sitemap Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Use this route to automatically generate a sitemap index for sites with over 50,000 URLs. The `page` parameter handles pagination, and `maxPerPage` can be customized. ```typescript // src/routes/sitemap[[page]].xml/+server.ts import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = async ({ params }) => { return await sitemap.response({ origin: 'https://example.com', page: params.page, // undefined on /sitemap.xml, "1"/"2"/"... on sub-pages maxPerPage: 45_000, // optional; defaults to 50_000 paramValues: { '/products/[id]': await fetchAllProductIds(), // e.g. 120,000 IDs }, }); }; /* * GET /sitemap.xml → sitemap index (when URLs > maxPerPage): * * * * https://example.com/sitemap1.xml * https://example.com/sitemap2.xml * https://example.com/sitemap3.xml * * * GET /sitemap1.xml → regular sitemap with URLs 1–45,000 * GET /sitemap2.xml → regular sitemap with URLs 45,001–90,000 * ... * * GET /sitemap.xml → regular sitemap (when URLs ≤ maxPerPage, no index needed) */ ``` -------------------------------- ### Multilingual Hreflang Annotations with Super Sitemap Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Configure the `lang` object to generate hreflang annotations for multilingual sites. Ensure routes are placed under a `[[lang]]` directory and prefix `paramValues` keys accordingly. ```typescript // src/routes/(public)/[[lang]]/sitemap[[page]].xml/+server.ts import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = async ({ params }) => { return await sitemap.response({ origin: 'https://example.com', page: params.page, lang: { default: 'en', alternates: ['zh', 'de'], }, paramValues: { // Prefix paramValues keys with /[[lang]]/ for translated routes '/[[lang]]/blog/[slug]': ['hello-world', 'another-post'], '/[[lang]]/campsites/[country]/[state]': [ ['usa', 'new-york'], ['canada', 'toronto'], ], }, excludeRoutePatterns: ['^/dashboard.*'], }); }; /* * Output for /about with lang config: * * * https://example.com/about * * * * * * https://example.com/zh/about * * * * * ... */ ``` -------------------------------- ### Generate Sitemap with Optional Route Parameters Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Use `paramValues` to specify values for optional route parameters or `excludeRoutePatterns` to suppress routes. Missing `paramValues` for an optional-param route will throw an error. ```typescript import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = async () => { return await sitemap.response({ origin: 'https://example.com', paramValues: { // '/something' is automatically included (no params needed) '/something/[[paramA]]': ['alpha', 'beta'], '/something/[[paramA]]/[[paramB]]': [ ['alpha', 'one'], ['beta', 'two'], ], }, // Alternative: exclude all variants of the route with a single pattern // (no trailing '$' means it matches all three URL depths) // excludeRoutePatterns: ['/something'], }); }; ``` -------------------------------- ### Configure Languages in Super Sitemap Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Specify the default language and alternate languages for your site. The default language will not appear in URLs, while alternates will be included. ```javascript lang: { default: 'en', alternates: ['zh', 'de'] } ``` -------------------------------- ### Use Sampled Paths in Playwright Tests Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Integrate sampledPaths into your Playwright tests to obtain a list of public paths. Ensure error handling for robustness. ```javascript // foo.test.js import { expect, test } from '@playwright/test'; import { sampledPaths } from 'super-sitemap'; let sampledPublicPaths = []; try { sampledPublicPaths = await sampledPaths('http://localhost:4173/sitemap.xml'); } catch (err) { console.error('Error:', err); } // ... ``` -------------------------------- ### Convert DB Results to Array of Arrays Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Transform database query results from an array of objects into an array of arrays of string values, suitable for dynamic route parameters. ```javascript const arrayOfArrays = resultFromDB.map((row) => Object.values(row)); // [['usa','new-york'],['usa', 'california']] ``` -------------------------------- ### Exclude Specific Paths with processPaths Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Use the `processPaths` callback to filter out specific paths from the sitemap. This is useful for excluding individual routes that cannot be handled by broader `excludeRoutePatterns`. Ensure the callback returns a `PathObj[]`. ```typescript return await sitemap.response({ // ... processPaths: (paths: sitemap.PathObj[]) => { const pathsToExclude = ['/zh/about', '/de/team']; return paths.filter(({ path }) => !pathsToExclude.includes(path)); }, }); ``` -------------------------------- ### Process Paths with `processPaths` Callback Source: https://context7.com/jasongitmail/super-sitemap/llms.txt Use the `processPaths` callback to filter and modify generated `PathObj` items. It receives all paths after route resolution and must return a modified array. Useful for excluding specific translated paths or adding trailing slashes. ```typescript import * as sitemap from 'super-sitemap'; import type { RequestHandler } from '@sveltejs/kit'; export const GET: RequestHandler = async () => { return await sitemap.response({ origin: 'https://example.com', paramValues: { '/[[lang]]/blog/[slug]': ['hello-world', 'draft-post', 'zh-only-post'], }, lang: { default: 'en', alternates: ['zh'] }, processPaths: (paths: sitemap.PathObj[]) => { // Example 1: exclude a specific translated path not yet available in English const exclude = new Set(['/zh/draft-post', '/zh-only-post']); paths = paths.filter(({ path }) => !exclude.has(path)); // Example 2: add a trailing slash to all non-root paths return paths.map(({ path, alternates, ...rest }) => ({ path: path === '/' ? path : `${path}/`, ...rest, alternates: alternates?.map((alt: sitemap.Alternate) => ({ ...alt, path: alt.path === '/' ? alt.path : `${alt.path}/`, })), })); }, }); }; /* * PathObj shape available inside processPaths: * { * path: '/blog/hello-world', * lastmod?: '2025-01-01T00:00:00Z', * changefreq?: 'daily', * priority?: 0.7, * alternates?: [{ lang: 'en', path: '/blog/hello-world' }, { lang: 'zh', path: '/zh/blog/hello-world' }] * } */ ``` -------------------------------- ### Playwright Test for Sitemap Validity Source: https://github.com/jasongitmail/super-sitemap/blob/main/README.md Implement a Playwright test to validate the sitemap.xml. This test checks for a 200 status code and valid XML structure, ensuring data integrity. ```javascript // /src/tests/sitemap.test.js import { expect, test } from '@playwright/test'; test('/sitemap.xml is valid', async ({ page }) => { const response = await page.goto('/sitemap.xml'); expect(response.status()).toBe(200); // Ensure XML is valid. Playwright parses the XML here and will error if it // cannot be parsed. const urls = await page.$$eval('url', (urls) => urls.map((url) => ({ loc: url.querySelector('loc').textContent, // changefreq: url.querySelector('changefreq').textContent, // if you enabled in your sitemap // priority: url.querySelector('priority').textContent, })) ); // Sanity check expect(urls.length).toBeGreaterThan(5); // Ensure entries are in a valid format. for (const url of urls) { expect(url.loc).toBeTruthy(); expect(() => new URL(url.loc)).not.toThrow(); // expect(url.changefreq).toBe('daily'); // expect(url.priority).toBe('0.7'); } }); ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.