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.
svelte/register) with sane defaults and customizable configuration.process.env.NODE_ENV and process.browser).opts.globalProps.opts.globalStores.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: { /* ... */ }
});
});
viewsDirnameType: String | String[].
Defaults to process.cwd() + "/views".
A directory or an array of directories for the app's views (svelte files).
bundlesDirnameType: 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.
bundlesPatternType: String.
Defaults to "[name]-[hash][extname]".
Bundles rollup output format. [name] will be used for easy reference at globalAssets.
bundlesHostType: String.
Defaults to "".
An optional host to prefix JS or CSS bundles. Eg, a CDN host or different subdomain.
defaultExtensionType: 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".
templateFilenameType: 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.
envType: 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.
devType: 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.
cacheType: Boolean.
Default is inferred with env. If env is "development" or "testing" is set to false.
hydratableType: 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.
legacyType: 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.
replaceType: 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.
preprocessType: Array.
Default is [].
Preprocess array to be used at rollup-plugin-svelte plugin.
dedupeType: 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'
]
cacheType: Boolean.
Overrides option set at the main config.
hydratableType: Boolean.
Overrides option set at the main config.
templateFilenameType: String.
Overrides option set at the main config or package's default.
propsType: Object.
Props passed to View svelte component. You will receive these props exporting each property in the view.
globalPropsType: Object.
Props passed global context accessible via getContext('global.props').
globalStoresType: 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'):
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.