A straightforward Svelte view engine for Express.
Install via npm.
npm install express-svelte --save
I created this project because of the lack of a simple way to create, compile, render and hydrate views for simple non-SPA web apps.
It is a view engine rather than an app framework (like svelte-kit, Sapper or Next.js).
It bypasses the express built-in view engine and instead it sets a res.svelte
function. The reason behind this is to avoid be tightly coupled with express (can be easily extended for use with Polka) and some limitations like the app.locals
and res.locals
merge logic.
- Static content without hydration.
- Hydration.
- Compile views asynchronously (no need of
svelte/register
) with sane defaults and customizable configuration.- Support for preprocess plugins.
- Replace values (like
process.env.NODE_ENV
andprocess.browser
). - Dedupe dependencies.
- Sourcemap support.
- Cache.
- Global values set at top-level component via Svelte Context API:
- Global props based on
opts.globalProps
. - Global stores based on
opts.globalStores
.
- Global props based on
- Customizable root lodash template (very fast and similar to EJS syntax).
Full setup example available at express-svelte-example.
const expressSvelte = require('express-svelte');
// ...
// Configure
app.use(expressSvelte({ /* config */ }));
// Render view
app.get((req, res, next) => {
res.svelte('View', {
props: { /* ... */ },
globalProps: { /* ... */ },
globalStores: { /* ... */ }
});
});
Type: String | String[]
.
Defaults to process.cwd() + "/views"
.
A directory or an array of directories for the app's views (svelte files).
Type: String | String[]
.
Defaults to process.cwd() + "/public/dist"
.
A directory or an array of directories for the app's views compiled bundles (js and css files) generated by the client rollup config.
Type: String
.
Defaults to "[name]-[hash][extname]"
.
Bundles rollup output format. [name]
will be used for easy reference at globalAssets
.
Type: String
.
Defaults to ""
.
An optional host to prefix JS or CSS bundles. Eg, a CDN host or different subdomain.
Type: String
.
Defaults to ".svelte""
.
Engine default extension resolution. The lookup has the same behavior as Express built-in res.render
function.
If you do res.svelte('View')
it will look for "View.svelte"
.
Type: String
.
Defaults to absolute path to package's default root lodash template.
If the default template does not fit for you, you can set a customized root template.
Type: Boolean
.
Defaults to process.env.NODE_ENV
or "development"
if not set.
Used to determine dev
and cache
values if not specified.
It replaces process.env.NODE_ENV
with @rollup/plugin-replace plugin by default.
Type: Boolean
.
Default is inferred with env
. If env
is "development"
or "testing"
is set to true
.
It sets dev
, preserveComments
and preserveWhitespace
properties at rollup-plugin-svelte plugin and enables source map support.
Type: Boolean
.
Default is inferred with env
. If env
is "development"
or "testing"
is set to false
.
Type: Boolean
.
Default is false
.
Hydratable value to be used at rollup-plugin-svelte plugin.
If disabled, props and globals won't be exposed in the HTML.
Type: Boolean
.
Default is true
.
A combination of modern and legacy builds will be used, the modern with type="module"
attribute and the legacy with the nomodule
attribute.
Browsers that understand type="module"
should ignore scripts with a nomodule
attribute. This means you can serve a module tree to module-supporting browsers while providing a fall-back to other browsers.
You can read the full article about this here.
If enabled, when using rollup-plugin-express-svelte it needs to be configured to build both bundles. You can check out the express-svelte-example.
Type: Object
.
Default is {}
.
Object with key-value pairs to be replaced with @rollup/plugin-replace plugin plugin.
Like process.env.NODE_ENV
replacement, a default replacement for process.env.browser
is made.
Type: Array
.
Default is []
.
Preprocess array to be used at rollup-plugin-svelte plugin.
Type: String[]
.
Default is []
.
Dependencies array to dedupe array to be used at @rollup/plugin-node-resolve plugin.
Every dependency you add will extend the following dedupe array:
[
'svelte',
'svelte/animate',
'svelte/easing',
'svelte/internal',
'svelte/motion',
'svelte/store',
'svelte/transition'
]
Type: Boolean
.
Overrides option set at the main config.
Type: Boolean
.
Overrides option set at the main config.
Type: String
.
Overrides option set at the main config or package's default.
Type: Object
.
Props passed to View svelte component. You will receive these props exporting each property in the view.
Type: Object
.
Props passed global context accessible via getContext('global.props')
.
Type: Object
.
Props passed global store accessible via getContext('global.stores')
.
For props
, each property can be accessed via export let propertyName
. You can use defaults too.
If you need to make data available globally to all components in the view you can set your values at:
For globalProps
accessed via getContext('global.props')
:
For globalStores
accessed via getContext('global.stores')
:
- The engine will create a svelte store for every first level value of the
globalStores
provided object.
Express example:
res.render('View', {
props: {
localValue: 1
},
globalProps: {
title: 'Some title!'
},
globalStores: {
user: { name: 'John' },
session: { sessionValue: 2 }
}
});
Svelte example: View.svelte
<script>
import { getContext } from 'svelte';
const { title } = getContext('global.props');
const { user, session } = getContext('global.stores');
export let localValue = null;
</script>
<svelte:head>
<title>{title}</title>
</svelte:head>
<span>{localValue}</span>
<span>{$user.name}</span>
<span>{$session.sessionValue}</span>
The variables it receives are:
head
: Output from<svelte:head>
component.style
: CSS code.globalProps
: Serialized global props.globalStore
: Serialized global store.props
: View props.script
: Script url.scriptLegacy
: Script url of legacy build.scriptModern
: Script url of modern build.hydratable
: Boolean indicating if the view is hydratable.legacy
: Boolean indicating if legacy support is enabled.html
: HTML code.
Also @nuxt/devalue function is provided to serialize props. This is made at template level to avoid serializing props that are not necessary according to hydration config.