diff --git a/.changeset/cuddly-suns-admire.md b/.changeset/cuddly-suns-admire.md new file mode 100644 index 0000000000..9b1f32fa09 --- /dev/null +++ b/.changeset/cuddly-suns-admire.md @@ -0,0 +1,5 @@ +--- +"create-t3-app": minor +--- + +feat: add a warning if nextuath url doens't match the port in dev diff --git a/cli/src/helpers/createProject.ts b/cli/src/helpers/createProject.ts index df50b78015..f239e3b9c2 100644 --- a/cli/src/helpers/createProject.ts +++ b/cli/src/helpers/createProject.ts @@ -40,6 +40,7 @@ export const createProject = async ({ scopedAppName, noInstall, appRouter, + packages, }); // Install the selected packages @@ -55,12 +56,6 @@ export const createProject = async ({ // Select necessary _app,index / layout,page files if (appRouter) { - // Replace next.config - fs.copyFileSync( - path.join(PKG_ROOT, "template/extras/config/next-config-appdir.mjs"), - path.join(projectDir, "next.config.mjs") - ); - selectLayoutFile({ projectDir, packages }); selectPageFile({ projectDir, packages }); } else { diff --git a/cli/src/helpers/scaffoldProject.ts b/cli/src/helpers/scaffoldProject.ts index d4e6730798..0e53abe550 100644 --- a/cli/src/helpers/scaffoldProject.ts +++ b/cli/src/helpers/scaffoldProject.ts @@ -14,6 +14,8 @@ export const scaffoldProject = async ({ projectDir, pkgManager, noInstall, + appRouter, + packages, }: InstallerOptions) => { const srcDir = path.join(PKG_ROOT, "template/base"); @@ -90,6 +92,15 @@ export const scaffoldProject = async ({ path.join(projectDir, ".gitignore") ); + // Select next.config.mjs + const configDir = path.join(PKG_ROOT, "template/extras/config/next-config"); + let filename = packages?.nextAuth.inUse ? "with-auth-" : "with-"; + filename += appRouter ? "appdir.mjs" : "pagedir.mjs"; + fs.copyFileSync( + path.join(configDir, filename), + path.join(projectDir, "next.config.mjs") + ); + const scaffoldedName = projectName === "." ? "App" : chalk.cyan.bold(projectName); diff --git a/cli/template/base/src/env.mjs b/cli/template/base/src/env.mjs index df4d160d14..2607bdd0fe 100644 --- a/cli/template/base/src/env.mjs +++ b/cli/template/base/src/env.mjs @@ -8,6 +8,7 @@ export const env = createEnv({ */ server: { NODE_ENV: z.enum(["development", "test", "production"]), + PORT: z.coerce.number().default(3000), }, /** @@ -25,6 +26,7 @@ export const env = createEnv({ */ runtimeEnv: { NODE_ENV: process.env.NODE_ENV, + PORT: process.env.PORT, // NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR, }, /** diff --git a/cli/template/extras/config/next-config-appdir.mjs b/cli/template/extras/config/next-config/with-appdir.mjs similarity index 100% rename from cli/template/extras/config/next-config-appdir.mjs rename to cli/template/extras/config/next-config/with-appdir.mjs diff --git a/cli/template/extras/config/next-config/with-auth-appdir.mjs b/cli/template/extras/config/next-config/with-auth-appdir.mjs new file mode 100644 index 0000000000..e25a66c10d --- /dev/null +++ b/cli/template/extras/config/next-config/with-auth-appdir.mjs @@ -0,0 +1,21 @@ +/** + * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful + * for Docker builds. + */ +import { env } from "./src/env.mjs"; + +// Warn if local development URL doesn't match with the active port +const nextAuthPort = new URL(env.NEXTAUTH_URL).port; +if (env.NODE_ENV === "development" && nextAuthPort !== String(env.PORT)) { + throw new Error( + [ + `❗ NEXTAUTH_URL (${env.NEXTAUTH_URL}) doesn't match with PORT (${env.PORT}).`, + `Either update your the URL in your .env file or make sure to run your dev server on port ${nextAuthPort}.`, + ].join(" ") + ); +} + +/** @type {import("next").NextConfig} */ +const config = {}; + +export default config; diff --git a/cli/template/extras/config/next-config/with-auth-pagedir.mjs b/cli/template/extras/config/next-config/with-auth-pagedir.mjs new file mode 100644 index 0000000000..702ec42b5f --- /dev/null +++ b/cli/template/extras/config/next-config/with-auth-pagedir.mjs @@ -0,0 +1,33 @@ +/** + * Run `build` or `dev` with `SKIP_ENV_VALIDATION` to skip env validation. This is especially useful + * for Docker builds. + */ +import { env } from "./src/env.mjs"; + +// Warn if local development URL doesn't match with the active port +const nextAuthPort = new URL(env.NEXTAUTH_URL).port; +if (env.NODE_ENV === "development" && nextAuthPort !== String(env.PORT)) { + throw new Error( + [ + `❗ NEXTAUTH_URL (${env.NEXTAUTH_URL}) doesn't match with PORT (${env.PORT}).`, + `Either update your the URL in your .env file or make sure to run your dev server on port ${nextAuthPort}.`, + ].join(" ") + ); +} + +/** @type {import("next").NextConfig} */ +const config = { + reactStrictMode: true, + + /** + * If you are using `appDir` then you must comment the below `i18n` config out. + * + * @see https://github.com/vercel/next.js/issues/41980 + */ + i18n: { + locales: ["en"], + defaultLocale: "en", + }, +}; + +export default config; diff --git a/cli/template/base/next.config.mjs b/cli/template/extras/config/next-config/with-pagedir.mjs similarity index 100% rename from cli/template/base/next.config.mjs rename to cli/template/extras/config/next-config/with-pagedir.mjs diff --git a/cli/template/extras/src/env/with-auth-db.mjs b/cli/template/extras/src/env/with-auth-db.mjs index afde07b1ea..8a3dd61d4b 100644 --- a/cli/template/extras/src/env/with-auth-db.mjs +++ b/cli/template/extras/src/env/with-auth-db.mjs @@ -17,6 +17,7 @@ export const env = createEnv({ NODE_ENV: z .enum(["development", "test", "production"]) .default("development"), + PORT: z.coerce.number().default(3000), NEXTAUTH_SECRET: process.env.NODE_ENV === "production" ? z.string() @@ -49,6 +50,7 @@ export const env = createEnv({ runtimeEnv: { DATABASE_URL: process.env.DATABASE_URL, NODE_ENV: process.env.NODE_ENV, + PORT: process.env.PORT, NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET, NEXTAUTH_URL: process.env.NEXTAUTH_URL, DISCORD_CLIENT_ID: process.env.DISCORD_CLIENT_ID, diff --git a/cli/template/extras/src/env/with-auth.mjs b/cli/template/extras/src/env/with-auth.mjs index d9e9b7cdcf..51b556b13a 100644 --- a/cli/template/extras/src/env/with-auth.mjs +++ b/cli/template/extras/src/env/with-auth.mjs @@ -10,6 +10,7 @@ export const env = createEnv({ NODE_ENV: z .enum(["development", "test", "production"]) .default("development"), + PORT: z.coerce.number().default(3000), NEXTAUTH_SECRET: process.env.NODE_ENV === "production" ? z.string() @@ -41,6 +42,7 @@ export const env = createEnv({ */ runtimeEnv: { NODE_ENV: process.env.NODE_ENV, + PORT: process.env.PORT, NEXTAUTH_SECRET: process.env.NEXTAUTH_SECRET, NEXTAUTH_URL: process.env.NEXTAUTH_URL, DISCORD_CLIENT_ID: process.env.DISCORD_CLIENT_ID, diff --git a/cli/template/extras/src/env/with-db.mjs b/cli/template/extras/src/env/with-db.mjs index 1107bd0faa..94786d2636 100644 --- a/cli/template/extras/src/env/with-db.mjs +++ b/cli/template/extras/src/env/with-db.mjs @@ -17,6 +17,7 @@ export const env = createEnv({ NODE_ENV: z .enum(["development", "test", "production"]) .default("development"), + PORT: z.coerce.number().default(3000), }, /** @@ -35,6 +36,7 @@ export const env = createEnv({ runtimeEnv: { DATABASE_URL: process.env.DATABASE_URL, NODE_ENV: process.env.NODE_ENV, + PORT: process.env.PORT, // NEXT_PUBLIC_CLIENTVAR: process.env.NEXT_PUBLIC_CLIENTVAR, }, /**