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元信息 - 提供运行时
useMetaUpdaterHook,监听路由变化并更新文档 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 buildE2E 示例工程
仓库内已提供可运行示例:
e2e/fixture
运行方式:
cd e2e/fixture
npm i
npm run dev示例文件
examples/meta.config.tsexamples/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
useMetaUpdaterhook 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-injectQuick 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
routesis not an object- meta fields are wrong types
- nested
metavalues 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 buildE2E Fixture
A runnable demo project is included at:
e2e/fixture
Run:
cd e2e/fixture
npm i
npm run devIncluded Example Files
examples/meta.config.tsexamples/vite.config.ts
License
MIT
