Skip to content

Instantly share code, notes, and snippets.

@swipswaps
Forked from PierBover/using-svelte-vercel.md
Created December 23, 2021 01:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swipswaps/eb0ab4a4155309cfed32c6ca60f6ca19 to your computer and use it in GitHub Desktop.
Save swipswaps/eb0ab4a4155309cfed32c6ca60f6ca19 to your computer and use it in GitHub Desktop.
Using Svelte in a Vercel serverless function

Using Svelte in a Vercel serverless function

The easiest way of using Svelte for SSR in Node is by using svelte/register. This allows to require .svelte files without any bundling and render HTML, CSS, etc.

This is the example from the docs:

require('svelte/register');

const App = require('./App.svelte').default;

const { html, css, head } = App.render({ answer: 42 });

If you do this in a Vercel serverless function it will work great locally while using vercel dev. However, once you deploy your function, it will break.

I'm not a Vercel expert, but this is how I've solved it.

1. Import the complete svelte package

It seems Vercel does some optimizations to reduce the size of the deployed functions so that only the required dependencies are bundled. It seems when doing require('svelte/register') Vercel will not bundle the complete svelte module and only the svelte/register folder. You function will break with this error:

Cannot find module '/var/task/node_modules/svelte/internal/index.js'

The solution is to do a dumb require of the whole module so that it gets bundled with your function:

require('svelte');
require('svelte/register');

2. Include all the .svelte files

Vercel will include all the .svelte files that you require in your functions, but it will ignore all the subsequent imports in your .svelte files. Svelte sub components that are not directly required in your serverless functions will not be bundled and your function will break.

The solution is simply to use the includeFiles directive in your vercel.json file:

{
  "functions": {
    "api/svelte-render.js": {
      "includeFiles": "api/_svelte/**"
    }
  }
}

Example Vercel serverless function

require('svelte');
require('svelte/register');

const Page = require('./_svelte/Page.svelte').default;

module.exports = async (request, response) => {

  const { html, css, head } = Page.render({});


  const fullHtml = `
    <!DOCTYPE html>
    <html>
    <body>
      ${html}
    </body>
    </html>
  `;

  response.setHeader('content-type', 'text/html; charset=UTF-8');
  response.send(fullHtml);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment