Bundle your Kirby frontend assets with Vite. The easiest way to get started is using the [basic starter kit](https://github.com/arnoson/kirby-vite-basic-kit) or the [multi-page kit](https://github.com/arnoson/kirby-vite-multi-page-kit).
## Usage
Make sure you have the right [setup](#setup).
Then inside your template files (or anywhere else) you can use the helper functions.
```php
= vite()->css('index.css') ?>
= vite()->js('index.js') ?>
```
## Setup
If you want use the plugin without one of the starter kits, you can add it to your existing kirby setup.
### Installation
```
composer require arnoson/kirby-vite
```
```
npm install vite vite-plugin-kirby
```
### Development VS Production modes
In development, files are loaded from Vite's dev server. In production, files are injected based on the `manifest.json` file generated by Vite.
kirby-vite uses a file named `.dev` (created and removed automatically by vite-plugin-kirby) to determine which mode to use:
- when the file exists, it will run in development mode
- when the file doesn’t exists, it will run in production mode
### Config
All configuration is done in the `vite.config.js`:
```js
// vite.config.js
import kirby from 'vite-plugin-kirby'
export default ({ mode }) => ({
// During development the assets are served directly from vite's dev server
// e.g. `localhost:5173/index.js`, but for production they are placed inside
// the `build.outDir`, `/dist/` in this case.
base: mode === 'development' ? '/' : '/dist/',
build: {
// Where your manifest an bundled assets will be placed. This example
// assumes you use a public folder structure.
outDir: 'public/dist',
assetsDir: 'assets',
// Your entry file(s).
// Note: CSS files can either be a separate entry. In this case you use it
// like this: `= vite->css('main.css') ?>`. Or you can only add the
// `main.js` as an entry and import the CSS in your JS file. In this case
// you would use the JS file name: `vite()->css('main.js')`.
rollupOptions: {
input: ['main.js', 'main.css'],
},
},
plugins: [
kirby({
// By default Kirby's templates, snippets, controllers, models, layouts and
// everything inside the content folder will be watched and a full reload
// triggered. All paths are relative to Vite's root folder.
watch: [
'../site/(templates|snippets|controllers|models|layouts)/**/*.php',
'../content/**/*',
],
// or disable watching
watch: false,
// Where the automatically generated `vite.config.php` file should be
// placed. This has to match Kirby's config folder!
kirbyConfigDir: 'site/config', // default
}),
],
})
```
`vite-plugin-kirby` shares part of this config with Kirby, by dynamically creating a `site/config/vite.config.php` file.
## Asset file paths
Sometimes you might want to access the (hashed) file path of your assets, e.g. to preload fonts. You can do so with `vite()->file()`:
```php
```
## Trying
If you try to load a non-existent manifest entry, this plugin will throw an error (if Kirby's `debug` option is enabled). This is intended behavior, since you usually know which entries exist. But sometimes, especially in a multi-page setup, you may want to try to load an entry only if it exists. You can do this with the `try` flag:
```php
vite()->js('templates/' . $page->template() . '.js', try: true);
vite()->css('templates/' . $page->template() . '.css', try: true);
vite()->file('maybe.woff2', try: true);
```
## Query Language
Since version `v5.3.0` you can use Kirby's query language in your entry names:
```php
vite()->js('templates/{{ page.template }}.js');
vite()->css('templates/{{ page.template }}.css');
```
Note: this will throw errors in debug mode if the assets don't exist. So you might want to use [Trying](#trying) to make the assets optional.
## Legacy build
Since version `2.4.0` you can easily support legacy browsers that do not support native ESM.
Just add the [@vitejs/plugin-legacy](https://github.com/vitejs/vite/tree/main/packages/plugin-legacy) plugin to your `vite.config.js`:
```js
import legacy from '@vitejs/plugin-legacy'
// vite.config.js
export default {
// ...
plugins: [
// ...
legacy(),
],
}
```
Now call kirby-vite's `js()` helper as usual.
```php
= vite()->js('index.js') ?>
```
which will render:
```html
```
## Panel CSS/JS
Since version `5.1.0` and **Kirby 4** you can bundle your panel assets alongside your other assets with vite. If you need this feature in Kirby 3, consider [kirby-laravel-vite](https://github.com/lukaskleinschmidt/kirby-laravel-vite/#custom-panel-scripts-and-styles).
Add your panel assets to vite:
```js
// vite.config.js
export {
// ...
build: {
rollupOptions: { input: ['src/your-other-assets.js', 'src/panel.js'] },
},
}
```
And configure Kirby. Make sure to use the [ready](https://getkirby.com/docs/reference/system/options/ready) callback, otherwise you won't be able to call the `vite()` helpers.
```php
fn() => [
'panel' => [
// If you have a `panel.js` file, that imports the `panel.css` file:
'css' => vite()->panelCss('panel.js'),
'js' => vite()->panelJs('panel.js'),
// If you only have a `panel.css` without a js file you must still use
// `vite()->panelJs()`, as this injects the vite client in development.
'css' => vite()->panelCss('panel.css'),
'js' => vite()->panelJs(),
],
],
];
```
Checkout the [example](https://github.com/arnoson/kirby-vite/tree/main/example) which includes a panel js/css setup.
### Known issue
`@vitejs/plugin-legacy` will inline the css in the legacy js entry. So users with a legacy browser will download the css twice. [See this issue](https://github.com/vitejs/vite/issues/2062).
## Contribution
PRs are welcome! If you are contributing it'd be great if you
- use conventional commits, so the release message can be auto-generated (and you are included in it!)
- format your code (if you are using vscode, this should happen automatically on save, otherwise use `npm run format`)
For quick manual testing, checkout the `/example` which uses the local vite and kirby plugin. When adding new features consider adding/improving tests in `/packages/kirby-vite/test` (right now we're only testing the kirby plugin).
Thanks :~)
## Credits
This plugin is highly inspired by [Diverently](https://github.com/Diverently)'s [Laravel Mix Helper for Kirby](https://github.com/Diverently/laravel-mix-kirby) and [André Felipe](https://github.com/andrefelipe)'s [vite-php-setup](https://github.com/andrefelipe/vite-php-setup). Many of the fine tunings I owe to [Johann Schopplich](https://github.com/johannschopplich) and his [Kirby + Vue 3 Starterkit](https://github.com/johannschopplich/kirby-vue3-starterkit).