Next.js 공식문서를 보면서 Next.js 13에서 추가된 점을 정리해보았습니다.
이전 글을 보신 후 이 글을 보시는 것을 추천드립니다. 잘못된 내용이 있다면 피드백 부탁드립니다.
Next.js Conf에서 발표한 바와 같이 Next.js 13은 제한 없이 동적으로 작동할 수 있는 토대를 마련합니다.
- app/디렉토리(Beta)
- 레이아웃
- React 서버 컴포넌트
- 스트리밍
- Turbopack(alpha)
next/image
(안정적)@next/font
(beta)- 상향된
next/link
Next.js 13에는 next/image 컴포넌트가 강력해졌습니다. 레이아웃 변경없이 이미지를 쉽게 표시하고 성능 향상을 위해 필요에 따라 파일을 최적화할 수 있습니다.
엄청나게 큰 차이는 없는 것 같다!
alt
속성을 필요로 하여 접근성 향상이전 버전의 next/image
컴포넌트는 next/legacy/image
로 변경되었습니다. 이전 버전에서 사용했던 next/image
를 next/legacy/image
로 변경해주는 codemod를 제공합니다.
// ./pages 디렉토리에 있는 코드들을 변경 시
npx @next/codemod next-image-to-legacy-image ./pages
Next.js 13에서 새로운 폰트 시스템을 소개하였습니다.
size-adjust
프로퍼티를 이용한 Layout shift 요소 제거@next/font에서는 google font를 제공합니다. CSS 및 글꼴 파일은 빌드 시 다운로드되며 나머지 정적 파일과 함께 자체 호스팅을 지원해줍니다. 더이상 폰트 사용을 위해 브라우저에서 Google 폰트 요청을 하지 않아도 됩니다.
개인적으로 제일 맘에 드는 부분인 것 같아요 🤩
구글폰트
import { Inter } from '@next/font/google';
const inter = Inter();
<html className={inter.className}>
커스텀폰트
커스텀폰트 역시 자동 호스팅, 캐싱 및 글꼴 파일 사전 다운로드를 지원합니다.
import localFont from '@next/font/local';
const myFont = localFont({ src: './my-font.woff2' });
<html className={myFont.className}>
next/link
는 더이상 자식요소로 <a>
태그를 필요로 하지 않습니다.
12.2 버전에서는 옵션으로 추가되었으며 이제는 기본값입니다. Next.js 13에서 <Link>
는 항상 <a>
를 렌더링 하고 기본태그에 props를 전달할 수 있습니다.
Before
import Link from 'next/link'
// Next.js 12: `<a>` has to be nested otherwise it's excluded
<Link href="/about">
<a>About</a>
</Link>
After(next.js 13)
import Link from 'next/link'
// Next.js 13: `<Link>` always renders `<a>`
<Link href="/about">
About
</Link>
업그레이드 된 next/link
를 사용하고 싶다면?
Next.js에서 next/link
를 자동으로 업데이트해주는 codemod를 제공합니다.
// ./pages 디렉토리에 있는 코드들을 변경 시
npx @next/codemod new-link ./pages
소셜 카드 혹은 개방형 그래프 이미지(open graph images)라고라는 OG Image는 콘텐츠 클릭의 참여율을 크게 높여줍니다.
정적 소셜 카드는 시간이 많이 소모되고, 오류가 발생하기 쉬우며 유지 관리가 어렵다는 단점이 있습니다. 이러한 단점 때문에 소셜카드를 건너뛰는 경우가 많습니다. 오늘날까지 동적 소셜 카드는 어렵고 비용이 많이 들었죠.
이번 Next.js 13에서 이러한 문제를 개선하고자 동적 소셜 카드를 생성하는 새로운 라이브러리인 @vercel/og
를 만들었습니다.
// pages/api/og.jsx
import { ImageResponse } from '@vercel/og';
export const config = {
runtime: 'experimental-edge',
};
export default function () {
return new ImageResponse(
(
<div
style={{
display: 'flex',
fontSize: 128,
background: 'white',
width: '100%',
height: '100%',
}}
>
Hello, World!
</div>
),
);
}
Middleware가 초기 디자인에 대한 피드백을 듣고 몇가지를 추가 및 수정되었습니다.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
export function middleware(request: NextRequest) {
// Clone the request headers and set a new header `x-version`
const requestHeaders = new Headers(request.headers);
requestHeaders.set('x-version', '13');
// You can also set request headers in NextResponse.rewrite
const response = NextResponse.next({
request: {
// New request headers
headers: requestHeaders,
},
});
// Set a new response header `x-version`
response.headers.set('x-version', '13');
return response;
}
이제 rewrite
나 redirect
필요 없이 직접 Middleware response로 제공할 수 있습니다.
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
import { isAuthenticated } from '@lib/auth';
// Limit the middleware to paths starting with `/api/`
export const config = {
matcher: '/api/:function*',
};
export function middleware(request: NextRequest) {
// Call our authentication function to check the request
if (!isAuthenticated(request)) {
// Respond with JSON indicating an error message
return NextResponse.json(
{
success: false,
message: 'Auth failed',
},
{
status: 401,
},
);
}
}
현재 Middleware에서 응답을 보내는 형식을 사용하려면 next.config.js
에서 별도 설정을 해주어야 합니다.
// next.config.js
const nextConfig = {
...
experimental: {
allowMiddlewareResponseBody: true
},
};
전체적으로 공식문서를 보고 작성하였고 어려운 부분은 아래 자료를 참고하여 작성하였습니다!
정리 감사합니다 ㅎㅎ