Có gì mới trong Nextjs 13? (phần 2)

By Thái Nguyễn
Picture of the author
Published on
image alt

Tiếp tục với Có gì mới trong Nextjs 13, trong bài viết này chúng ta sẽ cùng tìm hiểu các nội dung sau:

  • Parallel Routes and Interception
  • Custom route Handlers
  • Server Actions
  • Turpopack
  • Other upgrades

1. Parallel Routes and Interception

Trong bản cập nhật 13.3, nextjs đã giới thiệu dynamic conventions mới giúp chúng ta implement các routing cases nâng cao hơn đó là: Parallel Routes và Intercepting Routes.

1.1 Parallel Routes

Parallel Routes cho phép chúng ta render đồng thời hoặc có điều kiện 1 hoặc nhiều page trong cùng 1 layout.

Ví dụ, chúng ta có thể render đồng thời Team và Analytic Page trong cùng 1 layout:

ảnh ví dụ

Ưu điểm của Parallel Routing đó là cho phép định nghĩa các state một cách độc lập cho từng route như Loading, error, ... . Chúng cũng sẽ được stream độc lập => Tăng trải nghiệm người dùng.

Ví dụ minh hoạ @team@analytics có state và được stream độc lập:

ảnh ví dụ

Convention của Parallel Routes khá đơn giản. các slots sẽ được đặt tên có dạng @folder. Các Slots sẽ được pass vào layout cùng level như các props.

Ví dụ về file structure 2 slots @analytics và @team:

ảnh ví dụ

Với folder structure trên, app/layout,js sẽ nhận @analytics@team slots props và sẽ render chúng cùng với children prop:

app/layout.tsx

export default function Layout(props: {
  children: React.ReactNode
  analytics: React.ReactNode
  team: React.ReactNode
}) {
  return (
    <>
      {props.children}
      {props.team}
      {props.analytics}
    </>
  )
}
1.2 Intercepting Routes

Intercepting Routes cho phép chúng ta hiển thị nội dung của 1 route mà không cần thay đổi sang context khác.

Để hiểu rõ hơn thì mình sẽ làm 1 ví dụ theo cấu Folder structure như sau:

src
├── app
│   ├── intercepting
│   │   ├── (..)post
│   │   │   ├── page.tsx
│   │   ├── layout.tsx
│   │   ├── page.tsx
│   ├── post
│   │   ├── page.tsx
│   ├── layout.tsx
│   ├── page.tsx
├── component
│   ├── Modal.tsx

Đây sẽ là kết quả thu được:

Screen Recording 2023-08-16 at 15.46.43 (2)

Chúng ta sẽ có 2 Page chính: Intercepting và Post. Intercepting page sẽ chứa button để navigate sang page Post, và sẽ sử dụng chức năng Intercepting routes của nextjs 13 để hiển thị Modal Fake Post ( chính là (..)post trong folder intercepting ) thay vì load page Post. Khi nhấn ra ngoài Modal, sẽ back về page Intercepting và ẩn Modal.

(..) là convention của Intercepter Route.

Convention
  1. (.) to match segments on the same level
  2. (..) to match segments one level above
  3. (..)(..) to match segments two levels above
  4. (...) to match segments from the root app directory
Implement code

src/app/Post

  const Post = () => {
    return <div className="min-h-screen">This is a Post</div>;
  };

  export default Post;

src/app/intercepting/layout.tsx

  import React, { PropsWithChildren } from "react";

  const layout = ({ children }: PropsWithChildren) => {
    return (
      <div className="min-h-screen flex flex-col items-center justify-center gap-4">
        <div className="bg-green-400">This is intercept layout</div>
        <div>{children}</div>
      </div>
    );
  };

  export default layout;

src/app/intercepting/page.tsx

  import Link from "next/link";
  import React from "react";

  const Intercepting = () => {
    return (
      <div className="border-red-400 border p-2">
        <div className="mb-4">This is Intercepting page</div>
        <Link
          href="/post"
          className="bg-blue-500 h-10 flex flex-row items-center justify-center p-3 rounded-md text-white"
        >
          Go to post
        </Link>
      </div>
    );
  };

  export default Intercepting;

src/app/intercepting/(..)post

  import Modal from "@/components/Modal";
  import React from "react";

  const PostFake = () => {
    return (
      <Modal>
        <div className="text-red-100">PostFake inside intercepting</div>
      </Modal>
    );
  };

  export default PostFake;


6. Custom route Handlers

Trong Nextjs 12, để implement các API thì chúng ta sẽ khai báo trong folder pages/api. Để phân biệt các method khi sử dụng API theo nextjs 12 chúng ta thường làm như sau:

import type { NextApiRequest, NextApiResponse } from 'next'
 
export default function handler(req: NextApiRequest, res: NextApiResponse) {
  if (req.method === 'POST') {
    // Process a POST request
  } else {
    // Handle any other HTTP method
  }
}

=> Nhược điểm: cần thêm bước validate request method trước khi xử lý tiếp.

Từ version Nextjs 13.2, chúng ta có thể định nghĩa các API trong file được đặt tên là route.js|ts bên trong App folder.

app/api/route.ts


import { NextResponse } from 'next/server'
 
export async function GET() {
  const res = await fetch('https://data.mongodb-api.com/...', {
    headers: {
      'Content-Type': 'application/json',
      'API-Key': process.env.DATA_API_KEY,
    },
  })
  const data = await res.json()
 
  return NextResponse.json({ data })
}

Supported HTTP Methods

Route Handlers sẽ hỗ trợ các HTTP methods: GET, POST, PUT, PATCH, DELETE, HEAD, và OPTIONS. Nếu không hỗ trợ methods được gọi thì nó sẽ tự trả về lỗi 405 Method Not Allowed. Chúng ta sẽ không cần validate manually nữa.

Extended NextRequest and NextResponse APIs

Next.js extends native Request và Response ( Interface của Fetch API ) với NextRequest và NextResponse để cung cấp một cách thuận tiện và đáp ứng được những use case nâng cao hơn.

TypeScript Warning: mặc dù Response.json() là valid, nhưng hiện tại native TypeScript types sẽ hiển thị lỗi, bạn có thể thay thế bằng NextResponse.json() cho typed responses.


5. Server Actions ( alpha )

Server Actions are global Server Actions are API


7. Turpopack

8. Other upgrades

New next/image (stable) New @next/font (beta) Improved next/link