openElement is configured through Vite plugins. Routes, islands, static output, head injection, PWA, and middleware are independent concerns.
import { defineConfig } from 'vite'; import { openElement } from '@openelement/app/vite'; export default defineConfig({ plugins: [openElement()] });Use openElement() as the recommended entry - it combines the core plugin, content pipeline, and i18n in a single call. If you only need core routing and island functionality, you can use openPipeline() from @openelement/adapter-vite directly.
| Option | Default | Purpose |
|---|---|---|
| routesDir | 'app/routes' | Page routes, API routes, renderer and route-tree middleware. |
| islandsDir | 'app/islands' | Custom Elements for local client-side upgrade. |
| componentsDir | 'app/components' | Shared server-rendered components. |
| packageIslands | [] | Packages exporting an islands metadata array. This is not yet a full registry protocol. |
Future open add support should update this option only after a package manifest passes validation. Until then, third-party packages should be added explicitly and reviewed like any other dependency.
openElement v0.24.1 uses JSX+Signal as the component model. Configure deno.json and vite.config.ts:
// deno.json{"compilerOptions": {"jsx": "react-jsx", "jsxImportSource": "@openelement/core"}, "imports": {"@openelement/core/jsx-runtime": "jsr:@openelement/core@^0.24.1/jsx-runtime", "@openelement/core/jsx-dev-runtime": "jsr:@openelement/core@^0.24.1/jsx-runtime"}}// vite.config.tsexport default defineConfig({esbuild: {jsx: 'automatic', jsxImportSource: '@openelement/core',}, plugins: [openElement({ ... })]});jsx: 'automatic' tells esbuild to use openElement's jsx-runtime instead of React's. Both Vite SSR and client island builds will correctly transform .tsx files.
openElement({html: { lang: 'en', title: 'My App' }, inject: {stylesheets: ['https://cdn.example.com/theme.css'], headFragments: ['<meta name="theme-color" content="#050505">'],}, packageIslands: ['@openelement/ui'], middleware: { logger: true, cors: true, csp: { policy: "default-src 'self'" } }, pwa: { name: 'My App', shortName: 'openElement', themeColor: '#050505' }, content: { blog: { contentDir: 'posts' }, nav: { routesDir: 'app/routes' } }, i18n: { locales: ['en', 'zh'], defaultLocale: 'en' },});See API Reference for the complete options table, or check the Security & Middleware guide for CSP and middleware configuration.