v0.7.0
Go to GitHub repository

Assets Setup

Le-Kit ships a handful of static files that must be accessible at runtime from your web server. Without them, icons won't render and — if you use admin mode — the component property editor won't work.

The files you need to serve are:

  • Runtime bundle — the lazy-loading JS/CSS entry points (from node_modules/le-kit/dist/le-kit/)
  • Component assets — JSON icon definitions used by <le-icon> (from node_modules/le-kit/dist/components/assets/)
  • Custom Elements Manifest — component metadata used by the admin-mode property editor (from node_modules/le-kit/src/assets/custom-elements.json)

The simplest approach is to copy them all into a single directory under your public root, for example /public/le-kit/. The component assets must live in an assets/ sub-folder next to the bundle so that Stencil's internal path resolver finds them automatically — no extra configuration needed in that case.

Expected directory structure

public/
└── le-kit/
    ├── le-kit.esm.js       ← bundle entry (ES modules)
    ├── le-kit.js           ← bundle entry (no-module fallback)
    ├── le-kit.css          ← bundled styles
    ├── *.entry.js          ← lazy-loaded component chunks
    ├── assets/
    │   ├── icons/          ← JSON icon definitions
    │   └── custom-elements.json
    └── …

Astro

The easiest way in an Astro project is vite-plugin-static-copy, which runs during the Vite build and dev server.

Install the plugin
npm install -D vite-plugin-static-copy
astro.config.mjs
import { defineConfig } from 'astro/config';
import { viteStaticCopy } from 'vite-plugin-static-copy';

export default defineConfig({
  vite: {
    plugins: [
      viteStaticCopy({
        targets: [
          {
            // Runtime bundle (JS + CSS entry points + lazy chunks)
            src: 'node_modules/le-kit/dist/le-kit/*',
            dest: 'le-kit',
          },
          {
            // Icons — must live in assets/ next to the bundle
            src: 'node_modules/le-kit/dist/components/assets/*',
            dest: 'le-kit/assets',
          },
          {
            // Custom Elements Manifest (required for admin mode)
            src: 'node_modules/le-kit/src/assets/custom-elements.json',
            dest: 'le-kit/assets',
          },
        ],
      }),
    ],
  },
});

Then load the bundle in your base layout:

src/layouts/Layout.astro (inside <head>)
<script type="module" src="/le-kit/le-kit.esm.js"></script>
<noscript><script src="/le-kit/le-kit.js"></script></noscript>

Vite

The same vite-plugin-static-copy plugin works in any plain Vite project (Vue, Svelte, vanilla, etc.).

Install the plugin
npm install -D vite-plugin-static-copy
vite.config.ts
import { defineConfig } from 'vite';
import { viteStaticCopy } from 'vite-plugin-static-copy';

export default defineConfig({
  plugins: [
    viteStaticCopy({
      targets: [
        {
          src: 'node_modules/le-kit/dist/le-kit/*',
          dest: 'le-kit',
        },
        {
          src: 'node_modules/le-kit/dist/components/assets/*',
          dest: 'le-kit/assets',
        },
        {
          src: 'node_modules/le-kit/src/assets/custom-elements.json',
          dest: 'le-kit/assets',
        },
      ],
    }),
  ],
});

Add the script tag to your index.html:

index.html
<script type="module" src="/le-kit/le-kit.esm.js"></script>

Next.js

Next.js serves everything inside the public/ folder as static files, so you can copy the assets there as part of your install script. Add a postinstall script to your package.json:

package.json (excerpt)
{
  "scripts": {
    "postinstall": "node scripts/copy-le-kit-assets.mjs"
  }
}
scripts/copy-le-kit-assets.mjs
import { cpSync, mkdirSync } from 'node:fs';

const src = new URL('../node_modules/le-kit', import.meta.url).pathname;
const dest = new URL('../public/le-kit', import.meta.url).pathname;

mkdirSync(dest + '/assets', { recursive: true });

// Runtime bundle
cpSync(src + '/dist/le-kit', dest, { recursive: true });

// Icons
cpSync(src + '/dist/components/assets', dest + '/assets', { recursive: true });

// Custom Elements Manifest (admin mode)
cpSync(src + '/src/assets/custom-elements.json', dest + '/assets/custom-elements.json', { recursive: true });

console.log('Le-Kit assets copied to public/le-kit');

Then load the bundle from your root layout (e.g. app/layout.tsx):

app/layout.tsx
export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <head>
        <script type="module" src="/le-kit/le-kit.esm.js" />
      </head>
      <body>{children}</body>
    </html>
  );
}

webpack

Use copy-webpack-plugin to copy the assets during the build.

Install the plugin
npm install -D copy-webpack-plugin
webpack.config.js
const CopyPlugin = require('copy-webpack-plugin');
const path = require('path');

const leKitSrc = path.resolve(__dirname, 'node_modules/le-kit');

module.exports = {
  plugins: [
    new CopyPlugin({
      patterns: [
        {
          from: path.join(leKitSrc, 'dist/le-kit'),
          to: 'le-kit',
        },
        {
          from: path.join(leKitSrc, 'dist/components/assets'),
          to: 'le-kit/assets',
        },
        {
          from: path.join(leKitSrc, 'src/assets/custom-elements.json'),
          to: 'le-kit/assets/custom-elements.json',
        },
      ],
    }),
  ],
};

Custom asset paths

If you place the assets somewhere other than next to the bundle (for example in a CDN sub-path), you need to tell Le-Kit where to find them. Call configureLeKit before any component is rendered:

import { configureLeKit } from 'le-kit';

configureLeKit({
  // Path prefix used when loading icons
  assetBasePath: '/static/le-kit-assets',

  // URL of the Custom Elements Manifest (admin mode only)
  manifestFile: '/static/le-kit-assets/custom-elements.json',
});

When assetBasePath is set, icons will be fetched from {assetBasePath}/icons/{name}.json. When it is empty (the default), Stencil's built-in getAssetPath() is used instead, which resolves paths relative to the bundle file — so the default directory layout above works without any extra configuration.