What is the best way to run type checks and linting against Next.js apps in GitHub Actions when env variables are required? So I have check:types in a couple of my apps/* in my turborepo monorepo. At first I forgot to add next typegen in front of tsc –noEmit and got that resolved. However, now I am running into errors where env variables are needed. I’m not looking to deploy via GitHub actions, just to run type checks and other tests that might require env variables. I honestly don’t want to copy and paste my env variables from Vercel into GitHub.
Linting and typechecking doesn’t require running your app so the presence of environment variables shouldn’t actually come into account
If you have code like process.env.VERCEL_URL and you’re getting TS errors that it’s possibly undefined, you can guard the function with a reasonable error, and typescript will know that it’s defined in all usages after that
if (!process.env.VERCEL_URL) {
// ^? string | undefined
throw new Error ('VERCEL_URL not set')
}
process.env.VERCEL_URL
// ^? string
Alternatively, you can use the type assertion operator !to tell typescript you know the variable will be defined
process.env.VERCEL_URL!
Or use an approach like t3-env that allows you to define the environment variables your app uses in one place, get good errors when any aren’t present, and then access them in a type safe way
So I actually use @t3-oss/env-nextjs in this project, probably not to it’s full extent. However, when running next typegen && tsc –noEmity in my GitHub action I got
next typegen && tsc --noEmit
/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/@sanity+client@7.11.2_debug@4.4.3/node_modules/@sanity/client/dist/\_chunks-cjs/config.cjs:237
if (projectBased && !newConfig.projectId) throw new Error("Configuration must contain \`projectId\`");
^
Error: Configuration must contain \`projectId\`
at Object.initConfig (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/@sanity+client@7.11.2_debug@4.4.3/node_modules/@sanity/client/dist/\_chunks-cjs/config.cjs:237:53)
at SanityClient.config1 (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/@sanity+client@7.11.2_debug@4.4.3/node_modules/@sanity/client/dist/index.cjs:3566:132)
at new SanityClient (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/@sanity+client@7.11.2_debug@4.4.3/node_modules/@sanity/client/dist/index.cjs:3546:14)
at createClient (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/@sanity+client@7.11.2_debug@4.4.3/node_modules/@sanity/client/dist/index.cjs:3835:20)
at Object.<anonymous> (/home/runner/work/redshirt-sports/redshirt-sports/apps/web/next.config.compiled.js:133:39)
at Module.\_compile (node:internal/modules/cjs/loader:1706:14)
at requireFromString (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/next@15.5.4\_@babel+core@7.28.4\_@opentelemetry+api@1.9.0_babel-plugin-react-compiler@19.\_3878e06a270a097b6b5e5ecb81f7333e/node_modules/next/dist/build/next-config-ts/require-hook.js:81:7)
at transpileConfig (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/next@15.5.4\_@babel+core@7.28.4\_@opentelemetry+api@1.9.0_babel-plugin-react-compiler@19.\_3878e06a270a097b6b5e5ecb81f7333e/node_modules/next/dist/build/next-config-ts/transpile-config.js:98:51)
at async loadConfig (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/next@15.5.4\_@babel+core@7.28.4\_@opentelemetry+api@1.9.0_babel-plugin-react-compiler@19.\_3878e06a270a097b6b5e5ecb81f7333e/node_modules/next/dist/server/config.js:1060:36)
at async Module.nextTypegen (/home/runner/work/redshirt-sports/redshirt-sports/node_modules/.pnpm/next@15.5.4\_@babel+core@7.28.4\_@opentelemetry+api@1.9.0_babel-plugin-react-compiler@19.\_3878e06a270a097b6b5e5ecb81f7333e/node_modules/next/dist/cli/next-typegen.js:77:24)
Node.js v22.19.0
ELIFECYCLE Command failed with exit code 1.
So it looks like @sanity/client needs an env variable . Which is odd as I have node_modules in my exclude in my project’s tsconfig.json. It looks like @sanity/client is only used in my next.config.ts.
Ah that would do it, so Sanity has a hook that runs its own typegen when Next runs its typegen, and in order to do that it needs to connect to the Sanity server
So the only environment variable you’ll need to set up in Github Actions if you want typegen to work is what this Sanity plugin is looking for
Alternatively, you can conditionally create the sanity client in your next.config.ts file based on whether you’re in a Github Actions environment (some people like process.env.CI as a check for this) however that will be a type check that doesn’t fully match the production environment, so I would prefer the other option