많은 용량 차지 페이지 로딩 속도 + 사용자 경험
Webp, AVIF 등 차세대 이미지 포맷으로 변환 (브라우저 지원 확인)
사용자 화면에 맞게 이미지 크기 조절 불필요한 데이터 로드 최소화
스크롤을 올리거나 내려야 보이는 이미지는 나중에 필요할 때 불러오는 기법
최적화 과정을 자동으로 처리하는 Image 컴포넌트, 기존의 이미지 태그와 유사
export default function Page() {
return (
<Image src="/profile.png" width={500} heigth={500} alt="Picture of the author"/>
)
}
Image 컴포넌트에 fill Prop을 설정하면 자동으로 부모 요소를 꽉 채우도록 크기를 조정한다. (부모요소 크기가 설정)
export default function Example() {
return (
<div style={{ position: "relative", width: "100%", height: "300px" }}>
<Image src="/example.jjpg" alt="Example Image" fill />
</div>
);
}
외부 서버에서 제공하는 이미지는 허용하도록 설정하기
images.remotePatterns옵션을 추가로 설정
const nextConfig: NextConfig = {
/* config options here */
reactStrictMode: false,
logging: {
fetches: {
fullUrl: true,
}
},
images: {
remotePatterns: [
{
protocol: "https",
hostname: "shopping-phinf.pstatic.net",
}
]
}
};
앱 라우터 버전에서 검색 엔진 최적화(SEO)를 위해 파비콘, 메타 태그, 사이트맵 등 설정 방법을 살펴본다.
favicon.ico, thumbnail.png 파일을 public폴더로 옮긴다.
src폴더에 있던 favicon.ico파일 대체하기
export const metadata; Metadata = {
title: "한입북스",
description: "한입북스에 등록된 도서를 만나보세요.",
openGraph: {
title: "한입북스",
description: "한입북스에 등록된 도서를 만나보세요.",
images: ["/thumnail.png"],
},
};
metadata라는 변수를 선언, title, description, openGraph를 메타 데이터로 설정하면 자동 적용
개발자도구 Elements 탭에서 head 태그에 추가 된 메타 태그를 확인할 수 있다.
사용자 요청에 따라 실시간으로 바뀌는 쿼리 스트링 값은 반영할 수 없다.
동적 메타 데이터를 생성하는 generateMetadata라는 함수를 활용한다.
page.tsx에서 generateMetadata함수를 선언하고 내보내면 Next.js가 자동으로 함수의 반환값을 해당 페이지의 메타 태그로 설정한다.
export async function generateMetadata({ searchParams, }: {
searchParams: Promise<{ q?: string }>;
}) { const {q} = await searchParams;
}
검색 페이지의 페이지 컴포넌트를 위와 같이 수정한다.
구글이나 네이버의 검색 엔진 크롤러가 웹사이트 페이지, 동영상, 이미지 등 콘텐츠를 효율적으로 수집하도록 도와주는 파일이다.
= 웹사이트 페이지 구조를 검색 엔진에 알리는 용도로 사용된다.
사이트맵은 검색 엔진이 웹사이트의 콘텐츠를 더 빠르고 정확하게 크롤링하도록 도와준다.
https://winterload.com/sitemap.xml로 설정된다
sitemap 함수로 현재 데이터베이스에 등록된 모든 도서 목록 정보를 동적으로 불러온다.
import { BookData } from "@/types";
import { url } from "inspector";
import { MetadataRoute } from "next";
export default async function sitemap(): Promise<MetadataRoute.Sitemap>{
const response = await fetch(`${process.env.NEXT_PUBLIC_API_URL}/book`, {
cache: "force-cache",
});
if (!response.ok) throw new Error(response.statusText);
const allBooks: BookData[] = await response.json();
return [
{
url: "http://localhost:3000",
lastModified: new Date(),
},
{
url: "http://localhost:3000/search",
lastModified: new Date(),
},
...allBooks.map((book) => ({
url: `http://localhost:3000/book/${book.id}`,
lastModified: new Date(),
})),
]
}
url : 페이지 주소
lastModified : 페이지를 마지막으로 수정한 날짜 지정
changefreq : 페이지의 변경 빈도 (daily, weekly, monthly)
priority : 상대적 중요도 0.0 ~ 1.0 사이의 값
나중에 배포하기 위해
local.env에 BASE_URL을 등록하고 sitemap url에 BASE_URL을 넣기!