chore: new blog post about type safe env variables

nulfrost 983e6e49 7a68fe93

+2 -2
src/content/blog/supabase-auth-with-remix-and-vite.md
··· 12 12 This guide should also work for non-vite Remix projects but my preference is to use vite so we'll use a clean vite template. 13 13 14 14 ```bash 15 - npx create-remix@latest --template remix-run/remix/templates/vite 15 + npx create-remix@latest 16 16 ``` 17 17 18 18 Run this command in your terminal and follow the prompts, then open your new project in your editor of choice. You'll also need to [create a new project in supabase](https://supabase.com/) so that we can get access to the environment variables for this example. ··· 61 61 headers.append("Set-Cookie", serialize(key, "", options)); 62 62 }, 63 63 }, 64 - } 64 + }, 65 65 ); 66 66 67 67 return {
+108
src/content/blog/type-safe-environment-variables-in-remix.md
··· 1 + --- 2 + title: Type-safe environment variables in your Remix application using t3-env 3 + description: Quickly and easily add type-safety and runtime validation to your environment variables using the t3-env package. 4 + year: 2024 5 + published_at: 2024-04-05 6 + --- 7 + 8 + There are many was you can get type-safe variables in your projects, I've tried a few but recently found the t3-env package which makes it even easier and comes with some nice features as well. I will quickly walk through how to set this up in a Remix project. 9 + 10 + ## Install t3-env 11 + 12 + As of writing this, currently you can't just bring in any validation library so you will need to install `zod` as well. 13 + 14 + ```bash 15 + npm install @t3-oss/env-core zod 16 + ``` 17 + 18 + ## Create a new `env.server.ts` file 19 + 20 + Inside of the `/app` directory, create a file named `env.server.ts` and add the following code: 21 + 22 + ```typescript 23 + // app/env.server.ts 24 + 25 + import { createEnv } from "@t3-oss/env-core"; 26 + import { z } from "zod"; 27 + 28 + export const env = createEnv({ 29 + server: { 30 + DATABASE_URL: z.string().url(), 31 + // whatever else you may need 32 + }, 33 + }); 34 + ``` 35 + 36 + Then, to access the environment variables in your loaders or actions or anywhere you might need them, you would just need to import the `env` object and use it like this: 37 + 38 + ```typescript 39 + import { env } from "~/env.server"; 40 + 41 + export async function loader() { 42 + const dbUrl = env.server.DATABASE_URL; 43 + // do something with the dbUrl 44 + } 45 + ``` 46 + 47 + This is enough to get type-safety for your environment variables, but we can go even further. 48 + 49 + If you want to add runtime validation you just need to add a single property: 50 + 51 + ```typescript 52 + export const env = createEnv({ 53 + // ... 54 + runtimeEnv: process.env, 55 + }); 56 + ``` 57 + 58 + and then you'll need to import the `env.server.ts` file into the `entry.server.tsx` file like so: 59 + 60 + ```diff 61 + // app/entry.server.tsx 62 + 63 + import { PassThrough } from "node:stream"; 64 + 65 + import type { AppLoadContext, EntryContext } from "@remix-run/node"; 66 + import { createReadableStreamFromReadable } from "@remix-run/node"; 67 + import { RemixServer } from "@remix-run/react"; 68 + import { isbot } from "isbot"; 69 + import { renderToPipeableStream } from "react-dom/server"; 70 + + import "~/env.server.ts"; 71 + 72 + ``` 73 + 74 + On top of that, if you want to override the default error handler, you can do so like this: 75 + 76 + ```typescript 77 + export const env = createEnv({ 78 + onValidationError: (error) => { 79 + throw new Error( 80 + `Invalid environment configuration, missing the following variables: ${error.errors.map((error) => error.path[0]).join(", ")}`, 81 + ); 82 + }, 83 + // ... 84 + }); 85 + ``` 86 + 87 + Putting that all together you should end up with a file that looks like this: 88 + 89 + ```typescript 90 + // app/env.server.ts 91 + 92 + import { createEnv } from "@t3-oss/env-core"; 93 + import { z } from "zod"; 94 + 95 + export const env = createEnv({ 96 + onValidationError: (error) => { 97 + throw new Error( 98 + `Invalid environment configuration, missing the following variables: ${error.errors.map((error) => error.path[0]).join(", ")}`, 99 + ); 100 + }, 101 + server: { 102 + DATABASE_URL: z.string().url(), 103 + }, 104 + runtimeEnv: process.env, 105 + }); 106 + ``` 107 + 108 + If you want to see all of the features available in the t3-env package, I recommend checking out [the official documentation](https://env.t3.gg/docs/introduction).