|
1 | 1 | --- |
2 | | -last_modified: 2026-06-16 |
| 2 | +last_modified: 2026-07-07 |
3 | 3 | title: "Build a Next.js App" |
4 | 4 | description: "Walkthrough guide to building a Next.js application with Deno. Learn how to set up a project, create API routes, implement server-side rendering, and build a full-stack TypeScript application." |
5 | 5 | url: /examples/next_tutorial/ |
@@ -57,6 +57,23 @@ compatibility, update your `deno.json` file with the following configuration: |
57 | 57 | } |
58 | 58 | ``` |
59 | 59 |
|
| 60 | +Next.js reads `next.config.*` during local and Deploy builds. With Deno, prefer |
| 61 | +an ESM config file named `next.config.mjs`. Current Next.js releases also |
| 62 | +support `next.config.ts` with the same `export default` shape: |
| 63 | + |
| 64 | +```js title="next.config.mjs" |
| 65 | +/** @type {import('next').NextConfig} */ |
| 66 | +const nextConfig = {}; |
| 67 | + |
| 68 | +export default nextConfig; |
| 69 | +``` |
| 70 | + |
| 71 | +If you started from a scaffold that generated `next.config.js` with |
| 72 | +`module.exports`, Deno's `detect-cjs` option usually lets that CommonJS config |
| 73 | +work. If you still see `module is not defined`, or if a tool loads the config as |
| 74 | +an ES module, rename it to `next.config.mjs` and use `export default` as shown |
| 75 | +above. |
| 76 | + |
60 | 77 | Now install the dependencies found in the package.json: |
61 | 78 |
|
62 | 79 | ```sh |
@@ -178,9 +195,9 @@ export type Dino = { name: string; description: string }; |
178 | 195 | We'll update the `page.tsx` file in the `app` directory to fetch the dinosaur |
179 | 196 | data from our API and display it as a list of links. |
180 | 197 |
|
181 | | -To execute client-side code in Next.js we need to use the `use Client` directive |
182 | | -at the top of the file. Then we'll import the modules that we'll need in this |
183 | | -page and export the default function that will render the page: |
| 198 | +To execute client-side code in Next.js we need to use the `"use client"` |
| 199 | +directive at the top of the file. Then we'll import the modules that we'll need |
| 200 | +in this page and export the default function that will render the page: |
184 | 201 |
|
185 | 202 | ```tsx title="page.tsx" |
186 | 203 | "use client"; |
@@ -302,6 +319,24 @@ details! |
302 | 319 | Now that you have your working Next.js app, you can deploy it to the web with |
303 | 320 | Deno Deploy. |
304 | 321 |
|
| 322 | +:::tip Build troubleshooting |
| 323 | + |
| 324 | +If `next build` fails on Deno with |
| 325 | +`Cannot read properties of undefined (reading 'bold')`, the failure is in |
| 326 | +Next.js's build-time lint/type-check pass. A temporary workaround is to add |
| 327 | +`typescript.ignoreBuildErrors` and `eslint.ignoreDuringBuilds` to |
| 328 | +`next.config.mjs`, then run type checking and linting separately in CI. |
| 329 | + |
| 330 | +If a client component uses browser-only hooks or APIs, Next.js may still try to |
| 331 | +render it on the server during prerendering or SSR. Defer that code until after |
| 332 | +the component mounts, such as in `useEffect`. If you need to disable SSR with |
| 333 | +`next/dynamic` and `{ ssr: false }`, put the dynamic import in a Client |
| 334 | +Component wrapper; Server Components cannot use `{ ssr: false }` directly. |
| 335 | +Marking the route dynamic alone is not enough because dynamic routes still |
| 336 | +render on the server, where browser globals are undefined. |
| 337 | + |
| 338 | +::: |
| 339 | + |
305 | 340 | For the best experience, you can deploy your app directly from GitHub, which |
306 | 341 | will set up automated deployments. Create a GitHub repository and push your app |
307 | 342 | there. |
|
0 commit comments