npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@mvp-kit/vite-sitemap-plugin

v0.1.2

Published

Vite sitemap plugin for TanStack Router, explicit routes, and monorepo builds

Readme

@mvp-kit/vite-sitemap-plugin

npm version license

Keep your sitemap current with each Vite build.

@mvp-kit/vite-sitemap-plugin generates sitemap.xml from TanStack Router's routeTree.gen.ts, an explicit route list, or both. It writes to Vite's actual build output directory, works in monorepos, and can update robots.txt with the sitemap URL.

Features

  • Read TanStack Router routes from routeTree.gen.ts
  • Add explicit routes or load them asynchronously
  • Write to Vite's resolved build.outDir
  • Normalize and validate baseUrl
  • Skip unresolved dynamic routes such as /blog/$slug
  • Exclude routes by path, /** glob, regex, or predicate
  • Add lastmod, priority, changefreq, and image metadata per route
  • Append, overwrite, or skip robots.txt
  • Fail the build in strict mode

Sitemap indexes and sitemap splitting are not included in this release.

Install

npm install @mvp-kit/vite-sitemap-plugin

Quick Start

// vite.config.ts
import { defineConfig } from 'vite'
import { sitemapPlugin } from '@mvp-kit/vite-sitemap-plugin'

export default defineConfig({
  plugins: [
    sitemapPlugin({
      baseUrl: 'https://example.com',
      routes: ['/', '/about', '/pricing'],
    }),
  ],
})

Run vite build. The plugin writes sitemap.xml to Vite's resolved build.outDir.

TanStack Router

sitemapPlugin({
  baseUrl: 'https://example.com',
  routeTreePath: 'src/routeTree.gen.ts',
  routes: ['/blog/hello-world'],
  strict: true,
})

routeTreePath is resolved from Vite root. Routes from the route tree and routes are normalized, merged, and deduplicated.

Dynamic route patterns are skipped. Add concrete URLs through routes.

Explicit Routes

Use routes when URLs come from content, CMS data, or another route source.

sitemapPlugin({
  baseUrl: 'https://example.com',
  routes: async () => {
    const posts = await loadPublishedPosts()
    return ['/', '/docs', ...posts.map(post => `/blog/${post.slug}`)]
  },
})

Cloudflare Pages

// vite.config.ts
import { defineConfig, loadEnv } from 'vite'
import { sitemapPlugin } from '@mvp-kit/vite-sitemap-plugin'

export default defineConfig(({ mode }) => {
  const env = loadEnv(mode, process.cwd(), '')

  return {
    build: {
      outDir: 'dist',
    },
    plugins: [
      sitemapPlugin({
        baseUrl: env.PUBLIC_SITE_URL,
        routeTreePath: 'src/routeTree.gen.ts',
        strict: mode === 'production',
      }),
    ],
  }
})

Set PUBLIC_SITE_URL to the canonical URL, for example https://example.com.

robots.txt

By default, the plugin creates robots.txt when missing and appends a Sitemap: line when the file already exists.

sitemapPlugin({
  baseUrl: 'https://example.com',
  routes: ['/'],
  robotsTxt: {
    mode: 'overwrite',
    rules: ['User-agent: *', 'Disallow: /private'],
  },
})

Set robotsTxt: false or robotsTxt: { mode: 'skip' } to leave the file untouched.

Route Metadata

sitemapPlugin({
  baseUrl: 'https://example.com',
  routes: ['/', '/docs', '/blog/hello-world'],
  getRoutePriority: route => (route === '/' ? 1 : 0.8),
  getRouteChangefreq: route => (route.startsWith('/blog') ? 'weekly' : 'monthly'),
  getRouteLastmod: route => (route.startsWith('/blog') ? '2026-05-26' : undefined),
  getRouteImages: async route => (route === '/' ? ['/images/social-card.jpg'] : []),
})

priority must be between 0.0 and 1.0. changefreq must be one of always, hourly, daily, weekly, monthly, yearly, or never.

Options

| Option | Type | Default | Description | |--------|------|---------|-------------| | baseUrl | string | Required | Absolute site URL. Trailing slashes are removed. | | routeTreePath | string | undefined | TanStack Router route tree path, resolved from Vite root. | | routes | string[] \| (() => string[] \| Promise<string[]>) | [] | Explicit route list or async route loader. | | enabled | boolean | true | Enables sitemap generation. | | strict | boolean | false | Throws on URL warnings and generation errors. | | robotsTxt | boolean \| RobotsTxtOptions | { mode: 'append' } | Controls robots.txt output. | | excludeRoutes | RouteMatcher[] | [] | Excludes exact routes, /** globs, regex matches, or predicate matches. | | getRoutePriority | (route: string) => number | Built-in defaults | Returns sitemap priority from 0.0 to 1.0. | | getRouteChangefreq | (route: string) => Changefreq | Built-in defaults | Returns sitemap change frequency. | | getRouteLastmod | (route: string) => string \| Date \| undefined | Build date | Returns per-route lastmod. | | getRouteImages | (route: string) => string[] \| Promise<string[]> | undefined | Returns absolute or site-relative image URLs. | | verbose | boolean | false | Logs route-level details. |

type RouteMatcher = string | RegExp | ((route: string) => boolean)

type RobotsTxtOptions =
  | boolean
  | {
      mode?: 'append' | 'overwrite' | 'skip'
      rules?: string[]
    }

Output

<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
  <url>
    <loc>https://example.com/</loc>
    <lastmod>2026-05-26</lastmod>
    <changefreq>daily</changefreq>
    <priority>1</priority>
  </url>
</urlset>

Image metadata adds the image sitemap namespace and image:image entries.

License

MIT