Vite
The Vite plugin by nystudio107. The PHP bridge between Craft CMS and a Vite-based Node buildchain: reads Vite's manifest.json, resolves hashed filenames, and emits <script>/<link>/<style> tags in Twig. In dev mode it points at the Vite dev server (HMR); in production it reads the manifest.
nystudio107/craft-vite — free (MIT)
composer require nystudio107/craft-viteBuildchain setup lives elsewhere. This file documents only the plugin's runtime Twig API and config keys. For
config/vite.phpin full,vite.config.ts, multi-entry/per-page loading, DDEV dev-server config, and Tailwind v4 integration, see../vite-buildchain.md.
Documentation
- Overview: https://nystudio107.com/docs/vite/
- GitHub: https://github.com/nystudio107/craft-vite
- Craft Vite docs: https://craftcms.com/docs/5.x/development/vite.html
When unsure about a function or setting, WebFetch the docs page or read
src/variables/ViteVariable.php (+ the ViteVariableTrait from the shared
nystudio107/craft-plugin-vite package) for the authoritative signatures.
Common Pitfalls
- Using
entry()where you wantscript()—entry()returns a bare URL string;script()returns full<script>/<link>HTML. See the function table below. - Calling
register()and{{ }}-printing it —register()registers tags with the Yii2 view and returns empty markup. Use{% do craft.vite.register(...) %}, not{{ craft.vite.script(...) }}. - Expecting
includeCriticalCssTags()to work without critical CSS files — it reads fromcriticalPath+criticalSuffix. With no matching file it emits nothing. Critical CSS must be generated by the buildchain (e.g. thecriticalnpm step), not by the plugin. - Wrong function name — it is
includeCriticalCssTags(), notincludeCriticalCss(). - Forgetting
asset()for non-entry files — referencing a hashed asset (font, image bundled through Vite) with a raw path breaks in production.asset()resolves it through the manifest.
Twig API (craft.vite.*)
Signatures are verbatim from the plugin source (ViteVariable +
ViteVariableTrait).
| Function | Signature | Returns | Use |
|---|---|---|---|
script |
script(path, asyncCss = true, scriptTagAttrs = [], cssTagAttrs = []) |
Markup (<script> + <link> tags) |
Primary asset loader. Outputs complete tags for an entry point. |
register |
register(path, asyncCss = true, scriptTagAttrs = [], cssTagAttrs = []) |
Markup (registers with Yii2 view) |
Same as script() but registers tags with the view instead of printing them. Call with {% do %}. |
entry |
entry(path) |
Markup (URL string) |
Resolves a single manifest entry to a URL. Manifest-only — never the dev server. For manual tag construction. |
asset |
asset(path, public = false) |
Markup (URL string) |
URL for an arbitrary asset served through Vite (fonts, images). public: true for files in the public dir. |
integrity |
integrity(path) |
string |
Subresource-integrity hash for an entry (empty string if none). For manual integrity="..." attributes. |
inline |
inline(pathOrUrl) |
Markup |
Inlines a file's contents (Yii2 alias path or remote URL) directly into the page. |
devServerRunning |
devServerRunning() |
bool |
Whether the Vite dev server is reachable. Branch behaviour on dev vs prod. |
includeCriticalCssTags |
includeCriticalCssTags(name = null, attributes = []) |
Markup (<style>) |
Inlines the critical CSS file for a template wrapped in <style>. null auto-matches the current template. |
getCssInlineTags |
getCssInlineTags(path, attributes = []) |
string (<style>) |
Inlines a CSS file (by path or URL) wrapped in <style>. |
getCssHash |
getCssHash(path) |
Markup |
The hash of the first CSS file bundled with the given entry. |
script() — the common case
{# Load an entry point: full <script type="module"> + <link> tags #}
{{ craft.vite.script('src/js/app.ts', false) }}Param 2 (asyncCss): true (default) loads CSS via the media="print" onload
async pattern; false loads it synchronously (prevents FOUC). Params 3–4 add
attributes to the generated <script> / <link> tags. For placement, layout
blocks, and per-page entry loading, see ../vite-buildchain.md.
register() — defer tag output
{# Register now, let the Yii2 view place the tags — no direct output here #}
{% do craft.vite.register('src/js/contact.ts') %}asset() — non-entry files
<link rel="preload" href="{{ craft.vite.asset('src/fonts/inter.woff2') }}"
as="font" type="font/woff2" crossorigin>includeCriticalCssTags() — inline critical CSS
{%- block headStyles -%}
{{ parent() }}
{{ craft.vite.includeCriticalCssTags() }}
{%- endblock -%}Reads criticalPath + criticalSuffix (see config). Pass a template name to
target a specific critical file; null auto-matches the current template.
config/vite.php (keys)
Full config, environment-awareness, and DDEV setup are in
../vite-buildchain.md. The settings the plugin reads:
| Setting | Purpose |
|---|---|
useDevServer |
Use the Vite dev server with HMR (typically dev env only). |
manifestPath |
Path to Vite's manifest.json. |
devServerPublic |
Dev-server URL the browser uses. |
serverPublic |
Public URL prefix for built assets (prod). |
errorEntry |
Entry point(s) loaded on error templates. |
cacheKeySuffix |
Suffix for the plugin's internal cache key. |
devServerInternal |
Internal dev-server URL for the checkDevServer ping. |
checkDevServer |
Ping the dev server before emitting HMR URLs (enable for DDEV). |
includeReactRefreshShim |
Inject the React Fast Refresh shim (React only). |
includeModulePreloadShim |
Inject the modulepreload polyfill. |
includeScriptOnloadHandler |
Add an onload handler to generated scripts. |
criticalPath |
Directory of critical CSS files (includeCriticalCssTags()). |
criticalSuffix |
Filename suffix for critical CSS files. |