Vite¶
@easeo/vite injects SEO tags into the built index.html through Vite's
transformIndexHtml hook.
Prerequisites¶
- Node 20 or newer.
- Vite 4 or newer.
Install¶
Quick start¶
// vite.config.mjs
import { defineConfig } from "vite";
import easeo from "@easeo/vite";
export default defineConfig({
plugins: [
easeo({
config: {
canonicalHost: "example.com",
publicBaseUrl: "https://example.com",
siteName: "Example",
},
}),
],
});
Options¶
| Option | Type | Description |
|---|---|---|
config |
SEOConfig |
Required. Site-wide settings |
What it injects¶
For each built HTML page, the plugin adds:
<title>(fromconfig.siteName)<meta name="description"><link rel="canonical"><meta name="robots">- Open Graph tags
- Twitter Card tags
- a JSON-LD
<script>when a schema exists
The route is derived from the page path. A trailing index.html is stripped,
so /blog/index.html becomes /blog, while a path like /reindex is left
untouched.
Patterns¶
Multi-page builds¶
List every HTML entry point in build.rollupOptions.input; each becomes its own
route. See the Vite example.
Per-page metadata¶
The plugin only knows the route. For per-page titles and descriptions, prebuild
payloads with @easeo/core and merge them into the templates. See the
prebuild pattern.
Troubleshooting¶
| Symptom | Cause |
|---|---|
| Tags appear twice | The plugin and another plugin both inject a <title> |
| Wrong canonical for a page | The page is not listed in build.rollupOptions.input, so its path is unexpected |
| JSON-LD looks escaped | This is intentional: < is escaped so the value cannot close the script tag |
Notes¶
- The JSON-LD
childrenis a JSON string with<escaped, so it is safe to inject into a script tag. - For per-page metadata beyond path-derived defaults, use a framework with a data layer, or prebuild payloads and inject them yourself.