Sam Sabin
Sam Sabin

Reputation: 1167

How do you use process.env in SvelteKit?

I'm trying to connect a postgresql database with SvelteKit via Drizzle, using their nodejs package. I'm having a problem importing the database environment variables into the Drizzle config.

At first, I thought I could use SvelteKit's built-in modules ($env/static/private) via the SvelteKit documentation: Module Docs and Environment Variable Tutorial

My first attempt at a drizzle config looked like this:

drizzle.config.ts:

import { defineConfig } from 'drizzle-kit';
import { env } from '$env/static/public';

export default defineConfig({
  schema: './src/lib/server/schema.ts',
  out: './drizzle',
  dialect: 'postgresql',
  dbCredentials: {
    host: env.DB_HOST,
    port: env.DB_PORT,
    user: env.DB_USER,
    password: env.DB_PASSWORD,
    database: env.DB_NAME,
  },
});

But this implementation gives me the following error: _Cannot find module '$env/static/private' or its corresponding type declarations._. I researched this error and found the following Stack Overflow question addressing this problem: How to use environment variables in root files of you SvelteKit project?

From what I understand, because the Drizzle config is in the root, it is being processed by Vite before SvelteKit processes it? So either you have to move the Drizzle config to a nested folder within SvelteKit (Here's an example, except it's using the planetscale package instead of integrating directly), or you have to use process.env directly, despite $env/static/private having access to process.env variables (Here's an example of this method, again unfortunately dated). Here is also another example from a tutorial that seems to imply that you can have Drizzle config in root while also using $env/static/private, but the other Stack Overflow question seems to contradict this, and this example is also using the old version of Drizzle config syntax.

The problem I'm having is actually implementing process.env.

Do I need to import dotenv (I was under the impression that Svelte already includes it, but I'm not sure if I need to invoke it explicitly)? How do I make sure Typescript recognizes the typing of the env variables? Is it best practice to use process.env, or a nested folder format with the db (the other Stack Overflow question I referenced said that if I use a nested folder method then I won't be able to use Drizzle tools like drizzle-kit.), or is there really a way to use $env/static/private with config files in root?

I tried to follow a more generic example of process.env for Node using this Stack Overflow Question, but I'm quite confused. Here's my most recent attempt (still using a file in root), which gives me all kinds of errors:

import { defineConfig } from 'drizzle-kit';

declare var process : {
    env: {
      DB_HOST: string,
      DB_PORT: string,
      DB_USER: string,
      DB_PASSWORD: string,
      DB_NAME: string
    }
  }

export default defineConfig({
  schema: './src/lib/server/schema.ts',
  out: './drizzle',
  dialect: 'postgresql',
  dbCredentials: {
    host: process.env.DB_HOST,
    port: process.env.DB_PORT,
    user: process.env.DB_USER,
    password: process.env.DB_PASSWORD,
    database: process.env.DB_NAME,
  },
});

What is the best practice for using environment variables in SvelteKit, and how do I implement it?

Upvotes: 3

Views: 894

Answers (1)

Roeften
Roeften

Reputation: 434

I could not believe it when I discovered after reading the example for the 100th time, that I did not realise in sveltekit you must prepend the variables in static .env (in the project root) with PUBLIC_ and PRIVATE_.

Anything else is simply not injected and apparently no other method (vite, node) works out of the box at least.

So you can use the .env file to store the url or credentials and then

import { SECRET_DATABASE_URL } from '$env/static/private';

As for best practises obviously storing sensitive info in the .env is a better way. If you're using git make sure .env is in .gitignore (sveltekit did this automatically for me).

I do not think that if a file is on root this magic is not available, especially since you import it at some point to do the querying but my db config/instantiation is in $lib. I used knex but the process looks similar.

Upvotes: 0

Related Questions