Skip to content

Commit 78adbfe

Browse files
feat(web): add T3 Env schema
Ultra-worked with [Sisyphus](https://github.com/code-yeongyu/oh-my-opencode) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
1 parent 57dcb5c commit 78adbfe

4 files changed

Lines changed: 80 additions & 7 deletions

File tree

apps/web/next-env.d.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
/// <reference types="next" />
2+
/// <reference types="next/image-types/global" />
3+
import "./.next/dev/types/routes.d.ts";
4+
5+
// NOTE: This file should not be edited
6+
// see https://nextjs.org/docs/app/api-reference/config/typescript for more information.

apps/web/next.config.ts

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
import createNextIntlPlugin from "next-intl/plugin";
21
import type { NextConfig } from "next";
32

3+
import createNextIntlPlugin from "next-intl/plugin";
4+
import { env } from "./src/config/env";
5+
46
const withNextIntl = createNextIntlPlugin("./src/lib/i18n/request.ts");
57

6-
const isDev = process.env.NEXT_PUBLIC_ENABLE_DEVTOOLS === "true";
8+
const isDev = env.NEXT_PUBLIC_ENABLE_DEVTOOLS === "true";
79

810
const securityHeaders = [
911
{
@@ -72,6 +74,7 @@ const nextConfig: NextConfig = {
7274
experimental: {
7375
typedEnv: true,
7476
},
77+
serverExternalPackages: ["esbuild-wasm"],
7578
async headers() {
7679
return [
7780
{

apps/web/src/config/env.ts

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import { createEnv } from "@t3-oss/env-nextjs";
2+
import { z } from "zod";
3+
4+
export const env = createEnv({
5+
server: {
6+
BETTER_AUTH_SECRET: z.string().min(32, "Secret must be at least 32 characters"),
7+
BETTER_AUTH_URL: z.string().url().optional().default("http://localhost:3000"),
8+
GOOGLE_CLIENT_ID: z.string().optional().or(z.literal("")),
9+
GOOGLE_CLIENT_SECRET: z.string().optional().or(z.literal("")),
10+
GITHUB_CLIENT_ID: z.string().optional().or(z.literal("")),
11+
GITHUB_CLIENT_SECRET: z.string().optional().or(z.literal("")),
12+
FACEBOOK_CLIENT_ID: z.string().optional().or(z.literal("")),
13+
FACEBOOK_CLIENT_SECRET: z.string().optional().or(z.literal("")),
14+
OTEL_SERVICE_NAME: z.string().optional().default("web"),
15+
OTEL_SAMPLE_RATE: z
16+
.string()
17+
.optional()
18+
.default("0.1")
19+
.transform((val) => Number.parseFloat(val)),
20+
},
21+
22+
client: {
23+
NEXT_PUBLIC_BETTER_AUTH_URL: z.string().url().optional().default("http://localhost:3000"),
24+
NEXT_PUBLIC_API_URL: z.string().url().optional().default("http://localhost:8000"),
25+
NEXT_PUBLIC_SITE_URL: z.string().url().optional().default("https://example.com"),
26+
NEXT_PUBLIC_ENABLE_DEVTOOLS: z.enum(["true", "false"]).optional().default("false"),
27+
NEXT_PUBLIC_GIT_COMMIT: z.string().optional(),
28+
},
29+
30+
runtimeEnv: {
31+
BETTER_AUTH_SECRET: process.env.BETTER_AUTH_SECRET,
32+
BETTER_AUTH_URL: process.env.BETTER_AUTH_URL,
33+
GOOGLE_CLIENT_ID: process.env.GOOGLE_CLIENT_ID,
34+
GOOGLE_CLIENT_SECRET: process.env.GOOGLE_CLIENT_SECRET,
35+
GITHUB_CLIENT_ID: process.env.GITHUB_CLIENT_ID,
36+
GITHUB_CLIENT_SECRET: process.env.GITHUB_CLIENT_SECRET,
37+
FACEBOOK_CLIENT_ID: process.env.FACEBOOK_CLIENT_ID,
38+
FACEBOOK_CLIENT_SECRET: process.env.FACEBOOK_CLIENT_SECRET,
39+
OTEL_SERVICE_NAME: process.env.OTEL_SERVICE_NAME,
40+
OTEL_SAMPLE_RATE: process.env.OTEL_SAMPLE_RATE,
41+
NEXT_PUBLIC_BETTER_AUTH_URL: process.env.NEXT_PUBLIC_BETTER_AUTH_URL,
42+
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
43+
NEXT_PUBLIC_SITE_URL: process.env.NEXT_PUBLIC_SITE_URL,
44+
NEXT_PUBLIC_ENABLE_DEVTOOLS: process.env.NEXT_PUBLIC_ENABLE_DEVTOOLS,
45+
NEXT_PUBLIC_GIT_COMMIT: process.env.NEXT_PUBLIC_GIT_COMMIT,
46+
},
47+
48+
skipValidation: !!process.env.SKIP_ENV_VALIDATION,
49+
});

apps/web/tsconfig.json

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
{
22
"compilerOptions": {
33
"target": "ES2022",
4-
"lib": ["dom", "dom.iterable", "esnext", "webworker"],
4+
"lib": [
5+
"dom",
6+
"dom.iterable",
7+
"esnext",
8+
"webworker"
9+
],
510
"allowJs": true,
611
"skipLibCheck": true,
712
"strict": true,
@@ -11,17 +16,27 @@
1116
"moduleResolution": "bundler",
1217
"resolveJsonModule": true,
1318
"isolatedModules": true,
14-
"jsx": "preserve",
19+
"jsx": "react-jsx",
1520
"incremental": true,
1621
"plugins": [
1722
{
1823
"name": "next"
1924
}
2025
],
2126
"paths": {
22-
"@/*": ["./src/*"]
27+
"@/*": [
28+
"./src/*"
29+
]
2330
}
2431
},
25-
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx", ".next/types/**/*.ts"],
26-
"exclude": ["node_modules"]
32+
"include": [
33+
"next-env.d.ts",
34+
"**/*.ts",
35+
"**/*.tsx",
36+
".next/types/**/*.ts",
37+
".next/dev/types/**/*.ts"
38+
],
39+
"exclude": [
40+
"node_modules"
41+
]
2742
}

0 commit comments

Comments
 (0)