SvelteKit Static Site HTTP Headers
Tags: svelte, webdev, javascript
Published: 2021-11-08 10:21:57

---
title: "SvelteKit Static Site HTTP Headers"
published: "true"
description: "SvelteKit Static Site HTTP Headers: adding custom HTTP headers to your static SvelteKit site hosted on Cloudflare Pages, Render or Netlify."
tags: "svelte, webdev, javascript"
canonical_url: "https://rodneylab.com/sveltekit-static-site-http-headers/"
cover_image: "https://dev-to-uploads.s3.amazonaws.com/uploads/articles/vnvb6l01zrv15fugvrqw.png"
---

## ✨ What is a Static Site?

In this post we look at how to set up SvelteKit static site HTTP headers.  SvelteKit, similarly to tools like Next JS, lets you generate static as well as Server Side Rendered (SSR) sites.  SSR is not to be confused with a static site generator (SSG) which is a tool for generating static pages.   Static just means that the page is built once for all visitors (rather than custom built for every visitor) and is typically the same for every user.  An example is a typical blog or news site.  A site like Twitter however needs to show different content based on who logged in &mdash;  tweets from the people you follow, messages from your contacts and so on.  Typically since the content it different for every user, a static build will not suit this case.

You can create static sites in SvelteKit using the static adapter.  Using that adapter, you can deploy your site to <a href="https://developers.cloudflare.com/pages/framework-guides/deploy-a-svelte-site">Cloudflare Pages</a>, Netlify and <a aria-label="Read post about deploying static Svelte Kit site to Render" href="https://rodneylab.com/sveltekit-hosting/">Render</a> among other hosting providers.

We will first take a look at the uses for custom static headers, then have a quick run through the differences between setting SvelteKit static site HTTP headers for static sites and SSR sites. Finally we will look at how you might go about adding custom HTTP headers to your static SvelteKit site.  If that sounds appealing, let's read on!

## 😕 What do HTTP Headers do?

<a aria-label="Read more about H T T P Headers from M D N" href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers">HTTP headers are sent along with the body</a> as part fo the server response when you visit a website. The body contains the content you see while the headers contain meta data.  These are different to the HTML head section which is included in the response body.  As an example cookies are often sent in HTTP header responses from servers.  Another example are the dreaded CORS Access Control headers!  On your static site you might want to set custom HTTP headers to instruct search engine crawlers or bots not to crawl your site.  On top you can use then to boost your site's security.

Here's an example of an HTTP header instructing a bot not to index a page:

```
X-Robots-Tag: noindex
```

The HTTP headers are sent with a response from each page, and can be customised on a per-page basis.  This would be useful if you had some pages you were happy for search engines to index while not wanting them to index others.

## 🔌  <ElectricPlugEmoji /> Using the SvelteKit Static Adapter

Just like there are SvelteKit adapters for building SSR sites to run on Cloudflare Workers, Netlify, Node-based environments and Render, there is an adapter for building static sites.  Note you can <ExternalLink aria-label="See the static adapter on the Svelte Git Hub repo" href="https://github.com/sveltejs/kit/blob/master/packages/adapter-static/README.md">use the same SvelteKit static adapter for all the hosts</ExternalLink> mentioned above.  There is not too much to configuring it. First download the `next` version of the static the adapter into your project:

```shell
pnpm i -D @sveltejs/adapter-static@next
```

Then update you `svelte.config.js` file to use the adapter:

```javascript
/** @type {import('@sveltejs/kit').Config} */
import adapter from '@sveltejs/adapter-static';
 
const config = {
  kit: {
    adapter: adapter(),
    // hydrate the <div id="svelte"> element in src/app.html
    target: '#svelte'
	}
};
 
export default config
```

Note you can also go for the <em>half-in-half-out</em> option, where you make only some pages static.  In this case, you use the SSR adapter for your platform, then add this line to the load function in the Svelte file for any pages you want to static render:

```html
<script context="module">
	export const prerender = true;
  ...
</script>
```

## ⚖️ How is Adding Custom HTTP Headers different for Static Sites?

With server side rendered sites, you can use the `src/hooks.js` file to add any headers you want to the HTTP responses.  As an example you can <a aria-label="See an example of HTTP headers in the Svelte Kit M D sveX starter" href="https://github.com/rodneylab/sveltekit-blog-mdx/blob/main/src/hooks.js">take a peek at the SvelteKit MDsveX Starter</a>.

Because your node server, Lambda Function or Cloudflare worker which provides server side content sends the headers, you can update headers from the `hooks.js` file.  With a static site, it is the Cloudflare, Netlify or Render servers which respond directly to HTTP requests.  That does not mean you cannot add custom headers though!  Typically, you add a `_headers` file to your build directory and you're away (with Render you update the headers in the Dashboard). We'll look at this next.

## ⚙️ Adding Custom HTTP Headers to your Static SvelteKit Site

In the previous section we saw you need to add a `_headers` file to your SvelteKit build directory.  This will work with Cloudflare Pages and Netlify.  By default, your build directory will be `/build` in the root directory of your project.

Probably the easiest way to create the `_headers` file is to write a short script that generates it and update your `package.json` file's `build` script to run that script.  This way your host will generate the file automatically when you run builds.

To do this first update your `package.json` file:

```json
{
  "name": "sveltekit-blog-mdx",
  "version": "1.0.0",
  "scripts": {
    "dev": "svelte-kit dev --port 3000",
    "build": "svelte-kit build && node ./generate-headers",
    "preview": "svelte-kit preview --port 3000",
    "generate:headers": "node ./generate-headers.js",
  },
  ...
}
```

Then create a script which adds the headers you want in a `generate-headers.js` file in the root directory of your project:

```javascript
import fs from 'fs';
import path from 'path';
 
const __dirname = path.resolve();
const buildDir = path.join(__dirname, 'build');
 
function main() {
  const headers = `/*
  X-Frame-Options: DENY
  X-XSS-Protection: 1; mode=block
  X-Content-Type-Options: nosniff
  Referrer-Policy: same-origin
  Permissions-Policy: accelerometer=(), autoplay=(), camera=(), document-domain=(), encrypted-media=(), fullscreen=(), gyroscope=(), interest-cohort=(), magnetometer=(), microphone=(), midi=(), payment=(), picture-in-picture=(), publickey-credentials-get=(), sync-xhr=(), usb=(), xr-spatial-tracking=(), geolocation=()
  Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
`;
 
  const headersFile = path.join(buildDir, '_headers');
  fs.writeFileSync(headersFile, headers);
}
 
main();
```

This is just to give you an idea of what you might want to add.  You might consider adding <a aria-label="Learn ore about Content Security policy from Scott Helme" href="https://scotthelme.co.uk/content-security-policy-an-introduction/">Content Security Policy headers</a> or making the Permissions Policy headers less restrictive.  If your aim is improving security, run a test on <a href="https://securityheaders.com">securityheaders.com</a> or see the Mozilla Observatory as an alternative from this list of useful links:

- <a aria-label="Open up Content Security Policy Reference for docs"  href="https://content-security-policy.com/">Content Security Policy Reference</a>
- <a aria-label="Open Mozilla's Observatory site scanner" href="https://observatory.mozilla.org/">Observatory: Security Header site scanning from Mozilla</a>
- <a aria-label="Open Netlify's docs on the headers file" href="https://developers.cloudflare.com/pages/platform/headers">Cloudflare Pages custom headers docs</a>
- <a aria-label="Open Netlify's docs on the headers file" href="https://docs.netlify.com/routing/headers/#syntax-for-the-headers-file">Netlify docs on syntax for <code>_headers</code> file</a>

If you are hosting your static site on Render, you can <a aria-label="Learn how to add custom H T T P headers to your Render static site" href="https://render.com/docs/static-site-headers">add headers in the Render dashboard</a>.

## 🙌🏽 SvelteKit Static Site HTTP Headers: What we Learned

In this post we saw:

- what HTTP headers are,

- how SSR sites differ from static sites,

- a way you might include custom SvelteKit static site HTTP headers in your project.

I do hope there is at least one thing in this article which you can use in your work or a side project.  As always get in touch with feedback if I have missed a trick somewhere!

## 🙏🏽 SvelteKit Static Site HTTP Headers: Feedback

Have you found the post useful? Do you have your own methods for solving this problem? Let me know your solution. Would you like to see posts on another topic instead? Get in touch with ideas for new posts. Also if you like my writing style, get in touch if I can write some posts for your company site on a consultancy basis. Read on to find ways to get in touch, further below. If you want to support posts similar to this one and can spare a few dollars, euros or pounds, please <a aria-label="Support Rodney Lab via Buy me a Coffee" href="https://rodneylab.com/giving/">consider supporting me through Buy me a Coffee</Lianak>.

Finally, feel free to share the post on your social media accounts for all your followers who will find it useful. As well as leaving a comment below, you can get in touch via <a aria-label="Reach out on Twitter" href="https://twitter.com/messages/compose?recipient_id=1323579817258831875">@askRodney</a> on Twitter and also <a aria-label="Contact Rodney Lab via Telegram" href="https://t.me/askRodney">askRodney on Telegram</a>. Also, see <a aria-label="Get in touch with Rodney Lab" href="https://rodneylab.com/contact">further ways to get in touch with Rodney Lab</a>. I post regularly on <a aria-label="See posts on svelte kit" href="https://rodneylab.com/tags/sveltekit/">SvelteKit</a> as well as other topics. Also <a aria-label="Subscribe to the Rodney Lab newsletter" href="https://rodneylab.com/about/#newsletter">subscribe to the newsletter to keep up-to-date</a> with our latest projects.