Using secure environment variables in SvelteKit and Netlify
Tags: svelte, sveltekit, netlify
Published: 2021-08-01 17:04:27

If your project needs to access a private API key such as Stripe or a database, you have come to the right place. This process started after I needed to access a database with a private API key. The SvelteKit documentation (and dozens of other articles on the web) explains how you can expose your environment variables to your javascript using Vite, but what if you wanted to use them securely through a Netlify function?

## Step 1: Create your .env file
Create a file called `.env` in the root of your document. Inside, type a placeholder key/value pair such as:

```yaml
ENVIRONMENT=localhost
```

## Create the sample API file
Now that we have your new key defined, you'll need to create the API to read it. SvelteKit does things a little different in that it includes your APIs and pages inside a single folder called `routes`. Inside this folder, my personal preference is to create a new `api` folder to keep all the APIs separate from the pages. You could also disperse the APIs throughout your pages if you want. SvelteKit knows what is an API based on the `.svelte` or `.js` extension.

A *gotcha* here is that whatever you name the APIs, it can only be alphabetical names. Something like `_api` won't work since SvelteKit tries to render this as a special file.

Inside your new folder, create the new `helloWorld.js` file.

SvelteKit APIs are a little simpler than your standard Netlify function. Interestingly enough, when you build your project, SvelteKit includes all of your APIs together in a single `render.js` API.

## Setting up the API
Inside your new file, you'll want to set up the foundation like so:

```javascript
/**
 * @type {import('@sveltejs/kit').RequestHandler}
 */
export async function get(request) {
    const data = request.body;

    return {
        body: {
            message: "Hello World!"
        }
    };
}
```

In this example, this is an HTTP GET API. You can change that to `post()` for HTTP POST requests.

`const data = request.body;` returns any data that was sent along with the fetch request, such as with a fetch POST request.

## Setting up the environment variable
Now with our base API ready, we can include our new environment variable that we created. You'll need to use the [dotenv NPM package](https://www.npmjs.com/package/dotenv).

Since SvelteKit uses modules, you won't be able to use the `require()` statement. You'll have to use `import` instead, like so:

```javascript
import dotenv from 'dotenv';
dotenv.config();
```

This snippet will go at the very top of your new API file like so:

```javascript
import dotenv from 'dotenv';
dotenv.config();

/**
 * @type {import('@sveltejs/kit').RequestHandler}
 */
export async function get(request) {
    const data = request.body;

    return {
        body: {
            message: "Hello World!"
        }
    };
}
```


## Accessing the new environment values

Vite has a hard time reading environment values, and so you *must* reference it by bracket notation.
```javascript
// Wrong! This will return undefined
process.env.ENVIRONMENT;

// Correct! This will return 'localhost'
process.env['ENVIRONMENT'];
```

In your file, you can access the value securely by referencing with `process.env`. In our `helloWorld.js` file, let's call it in the return statement.

```javascript
import dotenv from 'dotenv';
dotenv.config();

/**
 * @type {import('@sveltejs/kit').RequestHandler}
 */
export async function get(request) {
    const data = request.body;

    return {
        body: {
            message: "Hello World from " + process.env['ENVIRONMENT']
        }
    };
}
```


## Setting up your SvelteKit project for Netlify
For all these pieces to connect properly, you'll have to use the Netlify Adapter. This is a SvelteKit requirement for deploying to a third party platform. Since we are using Netlify in this example, navigate to your `svelte.config.js` file in the root of your project, and add in:

```javascript
import adapter from '@sveltejs/adapter-netlify';
```

to the very top. After this, run `npm install` to install all the required packages. If you get an error, check your `package.json` file and make sure that the package looks something like this:

`"@sveltejs/adapter-netlify": "^1.0.0-next.25"`

That "next" is important since at the time of this writing, SvelteKit is still in beta.

Once the adapter is installed, you need to add it to your config information. Inside the same `svelte.config.js` file, you can add your adapter inside the `kit` property. That looks like this:

`adapter: adapter()`

Here is a basic example of the entire `svelte.config.js` file:

```javascript
import adapter from '@sveltejs/adapter-netlify';

/** @type {import('@sveltejs/kit').Config} */
const config = {
	kit: {
		// hydrate the <div id="svelte"> element in src/app.html
		target: '#svelte',

		// Svelte requires an adapter for deployment
		adapter: adapter()
	}
};

export default config;

```

Once that is done, you'll need to create your `netlify.toml` file so Netlify can read where your files go.

```toml
[build]
  command = "npm run build"
  publish = "build/"
  functions = "functions/"
```


## Testing to make sure it works
Before we do all the work to get this on Netlify, lets test the API locally. Spin up your SvelteKit site by typing `npm run dev` in your command line or terminal, and then open `http://localhost:3000` in your browser.

Navigate to your new API by following the paths you created in the `routes` folder. In my version, I added it under an `api` folder inside of `routes`. My path looks like:

`http://localhost:3000/api/helloWorld`

and you should see your new API response!

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/1v9m5cm2d473j4l4d1h7.png)


## Deploy your site to Netlify
Once you deploy to netlify, you'll need to set up your environment variable there. Navigate to your site settings, and click on Site Settings

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/je25jcnvctzk8l3vaiv2.png)

Choose Build & Deploy

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/3njl3rcfbzqpqs349dt9.png)

Then choose Environment

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/xjtf0b69l097s8oz5zn2.png)

click on the 'Edit variables' button, and add in a new variable called `ENVIRONMENT` (in all caps) and give it a value of `production`. 

Once you have saved this, you may need to redeploy your site to make sure the new ENVIRONMENT variable is being loaded correctly.


## Testing on Netlify

Navigate to your new API by following the paths you created in the `routes` folder. In my version, I added it under an `api` folder inside of `routes`. My path looks like:

`https://random-long-netlify-domain.netlify.app/api/helloWorld`

and you should see your new API using secure environment variables!

![image](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/zp3s6pig2v8p6wb1te2p.png)
 
Happy coding!