|
1 | 1 | # TanStack Router Sitemap Generator
|
| 2 | + |
| 3 | +Create an XML sitemap for your TanStack Router/Start based website. |
| 4 | + |
| 5 | +This package provides a `generateSitemap` function and a `sitemapPlugin` vite plugin. |
| 6 | + |
| 7 | +- Use the `sitemapPlugin` if you want to generate a static XML file during your Vite build. |
| 8 | +- Use the `generateSitemap` function to generate a sitemap at request time in a Server Function/API Route using TanStack Start. |
| 9 | + |
| 10 | +See the [configuration section](#sitemap-configuration) for more details on how to declare your sitemap. |
| 11 | + |
| 12 | +## Installation |
| 13 | + |
| 14 | +```bash |
| 15 | +npm install @tanstack/router-sitemap |
| 16 | +``` |
| 17 | + |
| 18 | +## Vite Plugin |
| 19 | + |
| 20 | +The `examples/react/basic` example includes a sitemap generated using the Vite plugin. |
| 21 | + |
| 22 | +```ts |
| 23 | +// vite.config.ts |
| 24 | +import { defineConfig } from 'vite' |
| 25 | +import { sitemapPlugin } from '@tanstack/router-sitemap/vite-plugin' |
| 26 | + |
| 27 | +export default defineConfig({ |
| 28 | + plugins: [ |
| 29 | + sitemapPlugin({ |
| 30 | + sitemap: { |
| 31 | + siteUrl: 'https://tanstack.com', |
| 32 | + routes: ['/', '/posts'], |
| 33 | + }, |
| 34 | + }), |
| 35 | + ], |
| 36 | +}) |
| 37 | +``` |
| 38 | + |
| 39 | +### Plugin Configuration |
| 40 | + |
| 41 | +| Property | Type | Default | Description | |
| 42 | +| --------- | --------------- | --------------- | --------------------------------------------- | |
| 43 | +| `sitemap` | `SitemapConfig` | Required | Sitemap configuration object | |
| 44 | +| `path` | `string` | `'sitemap.xml'` | Output file path relative to public directory | |
| 45 | + |
| 46 | +## Start API Route |
| 47 | + |
| 48 | +The `examples/react/start-basic` example includes a `sitemap.xml` API route. |
| 49 | + |
| 50 | +```ts |
| 51 | +// routes/sitemap[.]xml.ts |
| 52 | +import { createServerFileRoute } from '@tanstack/react-start/server' |
| 53 | +import { generateSitemap } from '@tanstack/router-sitemap' |
| 54 | +import { fetchPosts } from '~/utils/posts' |
| 55 | + |
| 56 | +export const ServerRoute = createServerFileRoute('/sitemap.xml').methods({ |
| 57 | + GET: async () => { |
| 58 | + const sitemap = await generateSitemap({ |
| 59 | + siteUrl: 'https://tanstack.com', |
| 60 | + routes: [ |
| 61 | + '/', |
| 62 | + [ |
| 63 | + '/posts/$postId', |
| 64 | + async () => { |
| 65 | + const posts = await fetchPosts() |
| 66 | + return posts.map((post) => ({ |
| 67 | + path: `/posts/${post.id}`, |
| 68 | + priority: 0.8, |
| 69 | + changefreq: 'daily', |
| 70 | + })) |
| 71 | + }, |
| 72 | + ], |
| 73 | + ], |
| 74 | + }) |
| 75 | + |
| 76 | + return new Response(sitemap, { |
| 77 | + headers: { |
| 78 | + 'Content-Type': 'application/xml', |
| 79 | + }, |
| 80 | + }) |
| 81 | + }, |
| 82 | +}) |
| 83 | +``` |
| 84 | + |
| 85 | +## Sitemap Configuration |
| 86 | + |
| 87 | +### Configuration Options |
| 88 | + |
| 89 | +| Property | Type | Required | Description | |
| 90 | +| ------------ | ------------------ | -------- | -------------------------------------------------------- | |
| 91 | +| `siteUrl` | `string` | Yes | Base URL of your website (e.g., `'https://example.com'`) | |
| 92 | +| `routes` | `Array<RouteItem>` | Yes | Array of routes to include in the sitemap | |
| 93 | +| `priority` | `number` | No | Default priority for all routes (0.0-1.0) | |
| 94 | +| `changefreq` | `ChangeFreq` | No | Default change frequency for all routes | |
| 95 | + |
| 96 | +### Route Configuration |
| 97 | + |
| 98 | +Route strings are inferred from your router similar to a `Link`'s `to` prop. |
| 99 | + |
| 100 | +Routes can be configured as: |
| 101 | + |
| 102 | +1. **Simple strings**: `'/'`, `'/about'` |
| 103 | +2. **Configuration tuples**: `['/route-path', options]` |
| 104 | + |
| 105 | +### Route Options |
| 106 | + |
| 107 | +| Property | Type | Description | |
| 108 | +| ------------ | --------------------------------------------------------------------------------- | ----------------------------------------------------- | |
| 109 | +| `path` | `string` | Custom path for dynamic routes | |
| 110 | +| `lastmod` | `string \| Date` | Last modification date | |
| 111 | +| `changefreq` | `'always' \| 'hourly' \| 'daily' \| 'weekly' \| 'monthly' \| 'yearly' \| 'never'` | How frequently the page changes | |
| 112 | +| `priority` | `number` | Priority of this URL relative to other URLs (0.0-1.0) | |
| 113 | + |
| 114 | +### Static Route Configuration |
| 115 | + |
| 116 | +```ts |
| 117 | +routes: [ |
| 118 | + '/', // Simple string |
| 119 | + ['/about', { priority: 0.9, changefreq: 'monthly' }], // With options |
| 120 | + ['/dynamic', async () => ({ lastmod: await getLastModified() })], // Async function |
| 121 | +] |
| 122 | +``` |
| 123 | + |
| 124 | +### Dynamic Route Configuration |
| 125 | + |
| 126 | +For routes with parameters, use functions that return arrays: |
| 127 | + |
| 128 | +```ts |
| 129 | +routes: [ |
| 130 | + [ |
| 131 | + '/posts/$postId', |
| 132 | + async () => { |
| 133 | + const posts = await fetchPosts() |
| 134 | + return posts.map((post) => ({ |
| 135 | + path: `/posts/${post.id}`, |
| 136 | + lastmod: post.updatedAt, |
| 137 | + priority: 0.8, |
| 138 | + changefreq: 'daily', |
| 139 | + })) |
| 140 | + }, |
| 141 | + ], |
| 142 | +] |
| 143 | +``` |
| 144 | + |
| 145 | +## Credit |
| 146 | + |
| 147 | +This package is partly based on an existing plugin from the community: [tanstack-router-sitemap](https://github.com/Ryanjso/tanstack-router-sitemap). |
0 commit comments