DEV Community

loading...

Using environment variables in SvelteKit (and Vite)

Dana Woodman
Software hacker working in the industry since 2003. Currently loves: #Typescript and #Svelte. Founder of Chimera, the first makerspace in northern California (https://www.chimeraarts.org/).
Updated on ・2 min read

UPDATE: the new Svelte FAQ now has this info in it (though I go into a little more detail here in case you're curious)


Setting environment variables in SvelteKit is as simple as creating a .env file at the base of your repo and add some content to it:

VITE_MESSAGE="World"
SOME_PRIVATE_VAR="You can't see me"
Enter fullscreen mode Exit fullscreen mode

Then, in your route or component, use import.meta.env.VAR:

<h1>Hello, {import.meta.env.VITE_MESSAGE}</h1>
Enter fullscreen mode Exit fullscreen mode

Which will get you "Hello, World".

Important note: Keys prefixed with VITE_ will be accessible to your components, routes and endpoints and other JS/TS code. Any key not prefixed cannot be imported to prevent leaking keys unintentionally.


Typescript

If you want to type your env vars in Typescript, you can extend ImportMetaEnv in your global.d.ts file:

interface ImportMetaEnv {
  VITE_MESSAGE: string
}
Enter fullscreen mode Exit fullscreen mode

If you want to use env vars in your endpoints or non-Svelte code and not get TS errors, you'll need to add "module": "es2020" to your tsconfig.json:

{
  "compilerOptions": {
    "module": "es2020",
    // ...
  }
  // ...
}
Enter fullscreen mode Exit fullscreen mode

Security note 🔐

Any environment variable prefixed with VITE_ has the potential to be leaked to the client browser if you use it in your Svelte components. Make sure to do the following to keep potential secrets safe:

  • ✅ ALWAYS: Only use secret keys in "endpoints" or other server-side code (e.g. a database connection string, auth token or secret)
  • 🛑 NEVER: do something like const env = import.meta.env in a component as now anyone can access all the values attached to env.
  • 🛑 NEVER: access your private environment variables in Svelte components or routes (e.g. DON'T do this in a component: console.log(import.meta.env.VITE_DATABASE_URL)).

Vite statically replaces any use of an environment variable so import.meta.env.VITE_FOO will compile down to "foo" assuming your .env has VITE_FOO="foo" in it.


Going further

You can read more about Vite's import.meta.env here

Note: you cannot use dynamic access of keys, e.g. this won't work: import.meta.env["VITE_MESSAGE"]. If you need dynamic variables, a solution would be to use svelte-preprocess's replace setting.


Fin

Well, that's it for today, give this post a 👍 / 🦄 / 🔖 if it was helpful for ya!

Follow me on Dev.to, Twitter and Github for more web dev and startup related content 🤓

Discussion (13)

Collapse
p6gb profile image
p6gb

This works fine with the svelte-kit dev script but crashes svelte-kit build with the following error: [rollup-plugin-dynamic-import-variables] Unexpected token (6:265) which points to the line where I use the imported variable in a .svelte file. Any idea why?

Collapse
danawoodman profile image
Dana Woodman Author

It crashes for you on npm run build? It is working fine for me on a fresh SvelteKit project, maybe you can try from scratch to eliminate variables? Do you have a specific adapter you're using?

Collapse
timdeschryver profile image
Tim Deschryver

This is probably because your svelte component includes a style tag?
timdeschryver.dev/blog/environment...

Collapse
p6gb profile image
p6gb

That might have been it. I am now adding the env variables to session in a hook:

export function getSession() {
    return {
        API_ENDPOINT: import.meta.env.VITE_API_ENDPOINT
    };
}
Enter fullscreen mode Exit fullscreen mode
Thread Thread
timdeschryver profile image
Tim Deschryver

That's smart!

Collapse
tonyketcham profile image
Tony Ketcham

Thank you! This helped me figure out the issue I was having when trying to import .env vars into my endpoints.

The SvelteKit project init had set the ecma version in my eslint parserOptions to 2019. Changing that to 2020 and defining the compilerOptions in my jsconfig.json fixed the issue.

Collapse
danawoodman profile image
Dana Woodman Author

Glad I could help!

Collapse
esojrafael profile image
Jose Rafael

Thanks for the post! Quick question, why would I declare any other variable besides VITE_* if I cant access it in endpoints. What if I have sensitive credentials that I need in an endpoint.

Collapse
danawoodman profile image
Dana Woodman Author

Great question, I don't know the reason Vite went this way ultimately, but I would assume you could have sensitive variables in .env and then import them where you need using dotenv or similar. Since Vite isn't designed for Svelte, it likely doesn't know if it is running in an endpoint vs a component, so I think that may be the root cause. Maybe you can prefix your private vars in a way so you don't accidentally like vars, like VITE_PRIVATE_SOME_SECRET_TOKEN?

Collapse
barmaleyhd profile image
Dmitry Nagorny

Same questions I had when just learned VITE_ concept. I'm not alone :)

Collapse
oncode profile image
Manuel Sommerhalder

Awesome article, now I'm even more excited to try out SvelteKit!

Collapse
danawoodman profile image
Dana Woodman Author

Awesome! That's the type of stuff I love to hear! 🤓

Collapse
jmpark6846 profile image
jmpark6846

thanks for this article. It was confusing to understand but now it became clear