[Survey] NextJs

v13 and up

:mag_right: Font

:bulb: Import google font from NextJs itself instead of css

:small_blue_diamond: Before

/* * Noto Sans TC (Chinese_traditional) http://www.google.com/fonts/earlyaccess */ @font-face { font-family: 'Noto Sans TC'; font-style: normal; font-weight: 100; src: url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Thin.woff2) format('woff2'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Thin.woff) format('woff'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Thin.otf) format('opentype'); } @font-face { font-family: 'Noto Sans TC'; font-style: normal; font-weight: 300; src: url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Light.woff2) format('woff2'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Light.woff) format('woff'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Light.otf) format('opentype'); } @font-face { font-family: 'Noto Sans TC'; font-style: normal; font-weight: 400; src: url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Regular.woff2) format('woff2'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Regular.woff) format('woff'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Regular.otf) format('opentype'); } @font-face { font-family: 'Noto Sans TC'; font-style: normal; font-weight: 500; src: url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Medium.woff2) format('woff2'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Medium.woff) format('woff'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Medium.otf) format('opentype'); } @font-face { font-family: 'Noto Sans TC'; font-style: normal; font-weight: 700; src: url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Bold.woff2) format('woff2'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Bold.woff) format('woff'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Bold.otf) format('opentype'); } @font-face { font-family: 'Noto Sans TC'; font-style: normal; font-weight: 900; src: url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Black.woff2) format('woff2'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Black.woff) format('woff'), url(//fonts.gstatic.com/ea/notosanstc/v1/NotoSansTC-Black.otf) format('opentype'); } html, body, #root, main { font-family: 'Noto Sans TC', '微軟正黑體', sans-serif; height: 100%; margin: 0; }

:small_blue_diamond: After

import { Inter } from "next/font/google"; const inter = Inter({ subsets: ["latin"] }); <body className={inter.className}></body> // will be: <body class="__className_aaf875"></body>
.__className_aaf875 { font-family: '__Inter_aaf875', '__Inter_Fallback_aaf875'; font-style: normal; }

:mag_right: Routing

:small_blue_diamond: Page routing

|── pages
│   ├── login.tsx
│   └── dashboard.tsx

:small_blue_diamond: App routing

In version 13, Next.js introduced a new App Router built on React Server Components, which supports shared layouts, nested routing, loading states, error handling, and more.[1]

The App Router works in a new directory named app. The app directory works alongside the pages directory to allow for incremental adoption.

|── app
│   ├── app1
│   └── app2

:bulb: Use App Router instead of Pages Router: The App Router takes priority over the Pages Router. Routes across directories should not resolve to the same URL path and will cause a build-time error to prevent a conflict.[1:1]

:small_blue_diamond: App routing tree







hierarchy



app

app



app1

app1



app->app1





app2

app2



app->app2


Subtree



[slug]

[slug]



app1->[slug]





(protected)

(protected)



app2->(protected)


Leaf



(public)

(public)



app2->(public)


Leaf



Created with Raphaël 2.2.0acme.comacme.com/dashboard/dashboard/settings/settingsURL PathDomainURL SegmentURL Segment

By default, components inside app are React Server Components. This is a performance optimization and allows you to easily adopt them, and you can also use Client Components.

:small_blue_diamond: use client

If encounter bellow error, then add 'use client' at the top of component file.

Screen Shot 2024-04-19 at 4.22.12 PM

Why?

To use Client Components, you can add the React use client directive at the top of a file, above your imports.

use client is used to declare a boundary between a Server and Client Component modules. This means that by defining a use client in a file, all other modules imported into it, including child components, are considered part of the client bundle.

'use client' import { useState } from 'react' export default function Counter() { const [count, setCount] = useState(0) return ( <div> <p>You clicked {count} times</p> <button onClick={() => setCount(count + 1)}>Click me</button> </div> ) }

However, use client doesn't need to be defined in every component that needs to be rendered on the client. Once you define the boundary, all child components and modules imported into it are considered part of the client bundle.[2]

:small_blue_diamond: Route Groups

:information_source: A route group can be created by wrapping a folder's name in parenthesis: (folderName)

To create multiple root layouts, remove the top-level layout.js file, and add a layout.js file inside each route groups. This is useful for partitioning an application into sections that have a completely different UI or experience. The <html> and <body> tags need to be added to each root layout.

├── app
│   ├── (app1)
│   │   ├── (protected)
│   │   │   ├── layout.tsx
│   │   │   ├── page.tsx
│   │   ├── (public)
│   │   │   ├── layout.tsx
│   │   │   ├── page.tsx    
│   │   ├── layout.tsx
│   ├── app2
│   │   ├── (protected)
│   │   │   ├── layout.tsx
│   │   │   ├── page.tsx       
│   │   ├── (public)
│   │   │   ├── layout.tsx
│   │   │   ├── page.tsx       
│   │   ├── layout.tsx

In the example above, both (app1) and app2 have their own root layout.

:no_entry: app2 could not be route group: Routes that include a route group should not resolve to the same URL path as other routes. For example, since route groups don't affect URL structure, (marketing)/about/page.js and (shop)/about/page.js would both resolve to /about and cause an error.

:vertical_traffic_light: If you use multiple root layouts without a top-level layout.js file, your home page.js file should be defined in one of the route groups, For example: app/(marketing)/page.js.[3]


  1. NextJs App Router official doc ↩︎ ↩︎

  2. NextJs Use client official doc ↩︎

  3. NextJs Route Group official doc ↩︎