Vite plugin
Source-accurate prompts and Tailwind detection for Vite-based React apps.
What it does#
Three things:
- Injects
data-wv-source="<file>:<line>:<col>"onto every JSX element in your project at dev-build time. The runtime reads this attribute to anchor prompts to source code. - Probes for Tailwind. If it finds
tailwind.config.{js,ts,mjs,cjs}or thetailwindcsspackage, it auto-enablestailwindVerbatimClassesfor the prompt generator. - Exposes a virtual module
virtual:weevar-configthat returns your merged config (weevar.config.json+weevar.config.js/mjs+ Tailwind probe results), so the runtime can pick it up without a separate file read.
The plugin runs in the pre phase, before @vitejs/plugin-react, so the JSX it transforms is the source you wrote, not React's output.
Install#
The plugin is bundled with the main package - no separate install.
npm install weevar
Register#
// vite.config.ts
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";
import { weevar } from "weevar/vite";
export default defineConfig({
plugins: [weevar(), react()],
});
Order matters. weevar() should come before react() so it sees the JSX before the React plugin transforms it.
What gets injected#
For every JSX opening tag (.jsx, .tsx) outside node_modules, the plugin appends an attribute like:
<NavItem data-wv-source="src/components/NavItem.tsx:12:4" />
The value is the path relative to your project root, plus the line and column where the tag begins. If a data-wv-source is already present (because you set it manually, or another plugin did), the existing one is kept.
Tailwind detection#
On startup, the plugin walks up from your project's cwd looking for:
tailwind.config.js/.ts/.mjs/.cjstailwindcsslisted inpackage.jsondependencies / devDependenciescontentglobs declared in your tailwind config
If any of those match, the merged config returned by the virtual module gets:
{
prompts: {
tailwindVerbatimClasses: true,
tailwindContentGlobs: [...], // when content globs are resolvable
tailwindConfigPath: "tailwind.config.ts",
}
}
You don’t need to set anything manually.
Virtual config module#
The plugin resolves virtual:weevar-config (with a leading null byte internally) to a small ES module that exports your merged config as the default. The runtime imports this lazily.
If you want to read it from your own code:
import config from "virtual:weevar-config";
console.log(config.prompts);
It's a frozen JSON value; no functions are evaluated at runtime.
Config precedence#
When the plugin builds the merged config, the order is:
- Default values (none - empty object)
weevar.config.jsonif it existsweevar.config.mjsorweevar.config.jsif it exists (JS wins on overlap; deep-merged)- Tailwind probe results (only set if not already specified)
- Inline
<Weevar config={...} />props (deep-merged at runtime)
See Config file → for the schema.
Opting out of source injection#
The plugin currently has no opt-out flag for source injection. If you need it skipped for a specific file, set data-wv-source manually on the relevant elements (it won't be overwritten) or move the file to a path the plugin doesn't match (e.g. node_modules).