Next.js Discord

Discord Forum

Cannot validate env at build time

Unanswered
Griffon Nivernais posted this in #help-forum
Open in Discord
Griffon NivernaisOP
Using Zod to apply type validation and intellisense to the necessary parts of env that I need, and for some reason they're being seen as undefined at build time despite there being an .env.development.local file. Here's the code:
import process from "process";
import { z } from "zod";

const schema = z.object({
    DATABASE: z.string(),
    DOMAIN: z.string().url(),
    NODE_ENV: z.union([z.literal("development"), z.literal("production")]).default("production"),
});

export default schema.parse({
    DATABASE: process.env.DATABASE,
    DOMAIN: process.env.DOMAIN,
    NODE_ENV: process.env.NODE_ENV ?? "production",
});

Here's the script I use to build:
    "build": "next build",

What could I be doing wrong?

4 Replies

Griffon NivernaisOP
Bump.
Griffon NivernaisOP
Bump.
Griffon NivernaisOP
I ended up doing a two-sided export, where if the schema parses it returns the typesafe env, otherwise it returns a constructed variant (and lies about the types for the env var). Have yet to come up with a better solution, error handling is put in place so that it's known in development and so runtime errors make sense.
import process from "process";
import { ZodError, z } from "zod";
import { ValidationError, fromZodError } from "zod-validation-error";

const schema = z.object({
    DATABASE: z.string(),
    DOMAIN: z.string().url(),
    NODE_ENV: z
        .union([z.literal("development"), z.literal("production"), z.literal("test")])
        .default("production"),
});
type Env = z.infer<typeof schema>;

let env: Env;

try {
    env = schema.parse({
        DATABASE: process.env.DATABASE,
        DOMAIN: process.env.DOMAIN,
        NODE_ENV: process.env.NODE_ENV ?? "production",
    });
} catch (error) {
    env = {
        DATABASE: process.env.DATABASE as string,
        DOMAIN: process.env.DOMAIN as string,
        NODE_ENV: process.env.NODE_ENV ?? "production",
    };

    if (error instanceof ZodError) {
        const validationError = fromZodError(error);

        console.warn(validationError.toString());
    }
}

export default env;