Your Web News in One Place

Help Webnuz

Referal links:

Sign up for GreenGeeks web hosting
August 30, 2022 09:50 pm GMT

Stages and Environment Variables in Svelte (SvelteKit)

While developing your Svelte application, you're likely to come across a scenario where you need to use different values depending on what stage (local, staging, production, etc.) the application is running on.

For example, lets say that you have the following +page.server.ts file which uses a load function that fetches blog posts from a local server, and passes them onto a +page.svelte route page:

+page.server.ts

import { error, type Load } from '@sveltejs/kit';export const load: Load = async () => {    const res = await fetch(`http://localhost:1337/api/blog-posts`);    const { data } = await res.json();    if (res.ok) {        return { posts: data };    }    throw error(404, 'Unable to fetch posts');};

Now, you've deployed your backend (API) and are ready to deploy your frontend (Svelte application) to production - only you can't yet, because the URL provided to fetch is pointing to localhost. We need that URL to fetch from our deployed API (let's pretend it's deployed to https://APP.herokuapp.com/api/blog-posts).

Obviously, we could replace the URL with our production one (https://APP.herokuapp.com/api/blog-posts), deploy it, and change it back to localhost (http://localhost:1337/api/blog-posts) whenever we're making local changes... but that would quickly become tedious.

How can we dynamically use different URLs depending on what stage the application is running on?

In more recent versions of SvelteKit, the build scripts used are the following:

"scripts": {  "dev": "vite dev",  "build": "vite build",  //...}

(This didn't use to be the case, they used to be svelte-kit dev and svelte-kit build respectively)

This means that we could (keep reading for a better solution) use Vite's MODE environment variable which is automatically provided to us. By default, the dev server (dev command) runs in development mode and the build command runs in production mode. (You can read more about modes here).

You can access environment variables via Vite using import.meta.env, so if you want to reference the MODE, you can use const { MODE } = import.meta.env (or const MODE = import.meta.env.MODE if you're not a fan of destructuring like myself).

Let's go back to the example, we could therefore add a ternary on the MODE which gives us:

+page.server.ts

import { error, type Load } from '@sveltejs/kit';const { MODE } = import.meta.env;const LOCAL_URL = 'http://localhost:1337/api/blog-posts';const PROD_URL = 'https://APP.herokuapp.com/api/blog-posts'; // Replace with whatever your deployed URL isexport const load: Load = async () => {    const res = await fetch(MODE === 'development' ? LOCAL_URL : PROD_URL);    const { data } = await res.json();    if (res.ok) {        return { blogs: data };    }    throw error(404, 'Unable to fetch blogs');};

Assuming your endpoint doesn't require an API key, the above should hit the correct endpoint and return the stage-specific data (). You can verify this by running npm run build to run the application in "production" mode.

How can we simplify this with custom .env variables?

Vite uses the dotenv package to load any additional environment variables in your envDir (which is defaulted to the root directory):

.env (loaded in all cases)
.env.local (loaded in all cases, ignored by git)
.env.[mode] (only loaded in specified mode)
.env.[mode].local (only loaded in specified mode, ignored by git)

Another couple of things to note:

  • An env file for a specific mode (e.g. .env.production) will take higher priority than a generic one (e.g. .env).
  • Additional environment variables must have the VITE_ prefix.

Knowing that, we can create the following...

.env.development (file in the root directory for the "development" mode)

contents:

VITE_API_URL=http://localhost:1337/api/blog-posts

.env.production (file in the root directory for the "production" mode)

contents:

VITE_API_URL=https://APP.herokuapp.com/api/blog-posts

...and we can simplify our load function by removing the ternary and by just using the VITE_API_URL environment variable. SvelteKit provides us with $env/static/public, so instead of using import.meta.env we can use import { VITE_API_URL } from '$env/static/private';, which gives us:

+page.server.ts

import { error, type Load } from '@sveltejs/kit';import { VITE_API_URL } from '$env/static/private';export const load: Load = async () => {    const res = await fetch(VITE_API_URL);    const { data } = await res.json();    if (res.ok) {        return { blogs: data };    }    throw error(404, 'Unable to fetch blogs');};

That's it!

If you need any further information on the above or anything else (eg. adding new environments such as staging) check out the Vite docs, the SvelteKit docs or the official Svelte discord.


Original Link: https://dev.to/willkre/stages-and-environment-variables-in-svelte-sveltekit-mdj

Share this article:    Share on Facebook
View Full Article

Dev To

An online community for sharing and discovering great ideas, having debates, and making friends

More About this Source Visit Dev To