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

vite-plugin-meta-inject_qianqian

v0.1.0

Published

Vite plugin for SPA SEO metadata injection and runtime updates.

Readme

vite-plugin-meta-inject

vite-plugin-meta-inject 是一个面向 SPA 的 Vite SEO 元信息插件。
它用于解决 <title>/<meta> 配置重复、页面切换难以动态更新的问题,支持构建期注入 + 运行时更新。

功能特性

  • 支持通过 meta.config.ts.mjs.json 进行页面级 Meta 配置
  • 支持静态路由与动态路由(基于 path-to-regexp
  • 基于 transformIndexHtml 在构建期自动注入 head 元信息
  • 提供运行时 useMetaUpdater Hook,监听路由变化并更新文档 Meta
  • 支持动态参数插值(如 {{id}}
  • 支持全局 Fallback 元信息兜底
  • 提供严格配置校验,错误时快速失败并中断构建
  • TypeScript 优先,提供完整类型定义
  • 基于 tsup 输出 ESM + CJS 双格式

安装

npm i vite-plugin-meta-inject

快速开始

1)创建 meta.config.ts

import type { MetaConfig } from "vite-plugin-meta-inject";

const config: MetaConfig = {
  fallback: {
    title: "我的 SPA",
    description: "默认描述",
    keywords: "vite,react,seo",
  },
  routes: {
    "/": {
      title: "首页",
      description: "首页描述",
    },
    "/blog/:id": {
      title: "博客详情 - {{id}}",
      description: "当前文章 ID 为 {{id}}",
    },
  },
};

export default config;

2)在 vite.config.ts 中注册插件

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import metaInject from "vite-plugin-meta-inject";

export default defineConfig({
  plugins: [react(), metaInject()],
});

3)运行时更新(React 19)

import { useLocation } from "react-router-dom";
import { useMetaUpdater } from "vite-plugin-meta-inject/runtime";
import metaConfig from "../meta.config";

function MetaSync() {
  const location = useLocation();
  useMetaUpdater({
    pathname: location.pathname,
    config: metaConfig,
  });
  return null;
}

插件 API

metaInject({
  configPath?: string; // 可选,自定义配置文件路径
  fallback?: MetaFields; // 可选,运行时 fallback 覆盖
  buildPath?: string; // 可选,构建期用于 transformIndexHtml 的路径,默认 "/"
});

配置结构

interface MetaFields {
  title?: string;
  description?: string;
  keywords?: string;
  meta?: Record<string, string>;
}

interface MetaConfig {
  fallback?: MetaFields;
  routes: Record<string, MetaFields>;
}

配置校验与报错

出现以下情况会立即中断构建:

  • 找不到配置文件
  • routes 不是对象
  • title/description/keywords 字段类型错误
  • meta 下存在非字符串值

报错示例:

[vite-plugin-meta-inject] Invalid meta config:
- routes must be an object with route pattern keys.
- routes["/blog/:id"].title must be a string.

动态参数插值

若路由配置为:

"/blog/:id": {
  title: "博客详情 - {{id}}",
}

当 pathname 为 /blog/42 时,最终标题会解析为 博客详情 - 42

性能目标

  • 插件加载耗时目标:<= 50ms
  • 运行时更新耗时目标:<= 10ms
  • 压缩后体积目标:<= 5KB(可执行 npm run size

当耗时超过目标值时,插件会输出性能告警日志。

开发命令

npm run lint
npm run test
npm run build

E2E 示例工程

仓库内已提供可运行示例:

  • e2e/fixture

运行方式:

cd e2e/fixture
npm i
npm run dev

示例文件

  • examples/meta.config.ts
  • examples/vite.config.ts

许可证

MIT

vite-plugin-meta-inject

vite-plugin-meta-inject is a Vite plugin for SPA SEO metadata management.
It solves repetitive <title>/<meta> maintenance and supports build-time injection + runtime route-based updates.

Features

  • Page-level meta config via meta.config.ts, .mjs, or .json
  • Static and dynamic route patterns (powered by path-to-regexp)
  • Build-time head injection via transformIndexHtml
  • Runtime useMetaUpdater hook for route-change updates
  • Dynamic placeholder interpolation ({{id}})
  • Global fallback metadata
  • Strict config validation with fail-fast build errors
  • TypeScript-first API and types
  • ESM + CJS bundles via tsup

Install

npm i vite-plugin-meta-inject

Quick Start

1) Add meta.config.ts

import type { MetaConfig } from "vite-plugin-meta-inject";

const config: MetaConfig = {
  fallback: {
    title: "My SPA",
    description: "Default description",
    keywords: "vite,react,seo",
  },
  routes: {
    "/": {
      title: "Home",
      description: "Home description",
    },
    "/blog/:id": {
      title: "Blog Detail - {{id}}",
      description: "Current article id is {{id}}",
    },
  },
};

export default config;

2) Register plugin in vite.config.ts

import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import metaInject from "vite-plugin-meta-inject";

export default defineConfig({
  plugins: [react(), metaInject()],
});

3) Runtime updates (React 19)

import { useLocation } from "react-router-dom";
import { useMetaUpdater } from "vite-plugin-meta-inject/runtime";
import metaConfig from "../meta.config";

function MetaSync() {
  const location = useLocation();
  useMetaUpdater({
    pathname: location.pathname,
    config: metaConfig,
  });
  return null;
}

Plugin API

metaInject({
  configPath?: string; // optional custom config path
  fallback?: MetaFields; // runtime fallback override
  buildPath?: string; // build-time path for transformIndexHtml, default "/"
});

Config Schema

interface MetaFields {
  title?: string;
  description?: string;
  keywords?: string;
  meta?: Record<string, string>;
}

interface MetaConfig {
  fallback?: MetaFields;
  routes: Record<string, MetaFields>;
}

Validation & Errors

Build fails immediately when:

  • config file is missing
  • routes is not an object
  • meta fields are wrong types
  • nested meta values are not strings

Error example:

[vite-plugin-meta-inject] Invalid meta config:
- routes must be an object with route pattern keys.
- routes["/blog/:id"].title must be a string.

Runtime Dynamic Placeholder

For a route config:

"/blog/:id": {
  title: "Blog Detail - {{id}}",
}

When pathname is /blog/42, title becomes Blog Detail - 42.

Performance Targets

  • Plugin config loading target: <= 50ms
  • Runtime update target: <= 10ms
  • Minified + gzip target: <= 5KB (use npm run size)

The plugin logs warnings when runtime/update timing exceeds configured targets.

Development

npm run lint
npm run test
npm run build

E2E Fixture

A runnable demo project is included at:

  • e2e/fixture

Run:

cd e2e/fixture
npm i
npm run dev

Included Example Files

  • examples/meta.config.ts
  • examples/vite.config.ts

License

MIT