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

@tavojs/sitemap

v1.0.2

Published

Sitemap and robots.txt generation for Tavo.js apps.

Readme

@tavojs/sitemap

Sitemap and optional robots.txt generation for Tavo.js applications.

The plugin discovers Tavo.js pages, serves files from SSR handlers, and emits build assets when its entry source is build-safe. The same configuration supports server-rendered and static deployments.

Install

npm install @tavojs/sitemap

Configure

import { defineConfig } from "@tavojs/core/config";
import { createSitemapPlugin } from "@tavojs/sitemap";

const sitemapPlugin = createSitemapPlugin({
  siteUrl: "https://example.com",
  robots: true
});

export default defineConfig({
  plugins: [sitemapPlugin]
});

Tavo.js pages with concrete paths are discovered automatically. For example, src/pages/about.tsx becomes /about, while route groups are omitted and optional parameters contribute their concrete base path.

Add entries only for dynamic URLs or to attach metadata to an automatically discovered page:

createSitemapPlugin({
  siteUrl: "https://example.com",
  entries: [
    {
      path: "/about",
      priority: 0.9
    },
    {
      path: "/blog/hello",
      lastModified: "2026-07-20",
      changeFrequency: "weekly"
    }
  ],
  robots: true
})

Explicit entries override automatically discovered entries at the same URL.

The manifest declares standard root exposure with an inspection-visible reason. Installing the plugin enables that exposure, so it creates:

  • /sitemap.xml
  • /robots.txt when robots is enabled
  • static build assets when the entries are build-safe

Use an application expose record only to remap the declared server tree, for example { plugin: sitemapPlugin, expose: { server: "/seo" } }.

Automatic Discovery

Discovery follows Tavo.js's file-route conventions:

  • includes ordinary static page files
  • removes route groups such as (marketing)
  • ignores layouts, error pages, 404, and private _ page files
  • includes the base path of optional parameters such as /docs/[[section]].tsx/docs
  • skips required dynamic and catch-all routes because they do not identify concrete URLs
  • reads a custom pagesDir from tavo.config.*

Exclude private or non-indexable areas explicitly:

createSitemapPlugin({
  siteUrl: "https://example.com",
  autoDiscover: {
    exclude: ["/admin/*", /^\/account(?:\/|$)/]
  }
})

Sitemap URLs follow the framework's resolved routing.trailingSlash policy by default. Override it for this sitemap with autoDiscover.trailingSlash:

createSitemapPlugin({
  siteUrl: "https://example.com",
  autoDiscover: {
    exclude: ["/admin/*"],
    trailingSlash: "always"
  }
})

Use "always", "never", or "preserve". The legacy boolean values true and false remain supported as aliases for "always" and "never". The root remains /, and file-like resources remain unchanged by "always".

Set autoDiscover: false to use only explicit entries.

Explicit Entries

createSitemapPlugin({
  siteUrl: "https://example.com",
  entries: [
    "/",
    "/about",
    {
      path: "/blog/hello",
      trailingSlash: "always",
      lastModified: "2026-07-20",
      changeFrequency: "weekly",
      priority: 0.8
    }
  ]
})

An entry object's trailingSlash setting overrides autoDiscover.trailingSlash and the framework policy for both its path and every URL in alternates. Queries are retained. File-like resources such as /llms.txt, /manifest.json, images, and /sitemap.xml never gain a trailing slash. Boolean entry overrides remain supported for backward compatibility.

Dynamic Entries

Use an async source when URLs come from a database or CMS:

createSitemapPlugin({
  siteUrl: "https://example.com",
  async entries({ request }) {
    const posts = await listPublishedPosts({ signal: request?.signal });
    return posts.map((post) => ({
      path: `/blog/${post.slug}`,
      lastModified: post.updatedAt
    }));
  }
});

Callback sources are request-time by default and are not executed during builds. Automatically discovered routes are still available to SSR responses. Set emitStatic: true when the callback is also safe and deterministic at build time; build calls receive { mode: "build" } without a request.

Localized Alternates

{
  path: "/about",
  alternates: {
    en: "/about",
    es: "/es/about",
    "x-default": "/about"
  }
}

All entry and alternate URLs must resolve to the configured siteUrl origin. The plugin rejects duplicates, fragments, invalid dates, invalid priorities, oversized output, and more than 50,000 URLs.

More Documentation

  • docs/framework-usage.md
  • docs/configuration.md
  • docs/testing-and-publishing.md

Project Policies