๐ก Next๋ ๋ชจ๋ ํ์ด์ง์ ๋ํ pre-rendering(Next.js๊ฐ client-side JavaScript๋ก ๋ชจ๋ ์์ ์ ์ํํ๋ ๋์ ๋ฏธ๋ฆฌ ๊ฐ ํ์ด์ง์ ๋ํด์ HTML์ ๋ง๋ค์ด๋๋ ๊ฒ)์ ์งํํด์ CSR๋ฐฉ์์ผ๋ก ๋ผ์ฐํ ์ ํ๋ค(SSG์ CSR์ ๊ฒฐํฉํ ๋ผ์ฐํ ๊ฐ๋ฅ). next์์๋ ๋๊ฐ์ง ํ์ด์ง ๋ผ์ฐํ ์ด ์กด์ฌํ๋ค.
1. next/link๋ก routing
- lazyํ ๋ฐฉ์์ผ๋ก ํ์ผ์ ๊ฐ์ ธ์ค๊ฒ ๋์ด ์ ์ ๋คํธ์ํฌ ์์ฒญ
(lazy loading์ ํ์ด์ง๋ฅผ ์ฝ์ด๋ค์ด๋ ์์ ์ ์ค์ํ์ง ์์ ๋ฆฌ์์ค ๋ก๋ฉ์ ์ถ ํ์ ํ๋ ๊ธฐ์ )<a>
ํ๊ทธ๋ก ์๋ ๋ณํ- SEO ๋ณด์ฅ O
2. next/router๋ก routing
- next/link์ฒ๋ผ ์๋์ผ๋ก prefetch๊ฐ ์๋๋ค.
- SEO ๋ณด์ฅ X
Pre-rendering์ ์๋ฒ์์ ํ์ด์ง๋ฅผ ๋น ๋ฅด๊ฒ ๋ ๋๋งํ ์ ์๊ฒ ํด์ฃผ๊ณ , prefetching์ ์ฌ์ฉ์๊ฐ ๋ค์์ ์ก์ธ์คํ ํ์ด์ง์ ๋ฐ์ดํฐ๋ฅผ ๋ฏธ๋ฆฌ ๋ก๋ฉํ์ฌ ๋น ๋ฅธ ํ์ด์ง ์ ํ์ ๊ฐ๋ฅํ๊ฒ ํ๋ค.
<a>
<a>
๋ก ์๋ ๋ณํ๋๋ฉฐ <a>
๋ฅผ ์์ ํ ๋์ฒดํ ์ ์๊ธฐ์ <Link>
์ ์คํ์ผ๋ง์ ๋ฐ๋ก ์
ํ ์ ์๋ค.<Link>
๊ฐ <a>
๋ฅผ ์์ ํ ๋์ฒดํ์ง ๋ชปํ๊ธฐ ๋๋ฌธ์ ์ง์ ์์์ผ๋ก aํ๊ทธ๋ฅผ ๋ฃ์ด์คฌ์ด์ผ ํ์import {useRouter} from 'next/router';
...
const router = useRouter();
๊ธฐ์กด <a>
ํ๊ทธ๋ก ์ด๋ํ๋ฉด ์ด์ ์ ์ ํ์ด์ง๋ผ๋ ์๋ฒ์ ๋ค์ ์์ฒญํด ๋ฐ์ดํฐ๋ฅผ ๋ฐ์์์ผ ํ์ง๋ง, next/link๋ฅผ ์ฌ์ฉํ๋ฉด ์ด์ ์ ๋ฐ์์จ ๋ฐ์ดํฐ๋ ๋ค์ ์์ฒญํ์ง ์์
์ฝ๋ ๋ถํ ์๋ ์ํํ๋ฏ๋ก ๊ฐ ํ์ด์ง๋ ํด๋น ํ์ด์ง์ ํ์ํ ๊ฒ๋ง ๋ก๋ํ๋ค. ์ฆ, ํํ์ด์ง๊ฐ ๋ ๋๋ง๋ ๋ ๋ค๋ฅธ ํ์ด์ง์ ์ฝ๋๋ ์ฒ์์ ์ ๊ณต๋์ง ์์ผ๋ฉฐ ์์ฒญํ ํ์ด์ง์ ์ฝ๋๋ง ๋ก๋ํ๋ฉด ํ์ด์ง๊ฐ ๊ฒฉ๋ฆฌ๋๋ค. ์ด๋ ํน์ ํ์ด์ง์์ ์ค๋ฅ๊ฐ ๋ฐ์ํ๋๋ผ๋, ๋๋จธ์ง ์ ํ๋ฆฌ์ผ์ด์ ์ ๊ณ์ ์๋ ๊ฐ๋ฅํ๋ค๋ ๊ฒ์ด๋ค.
production build์์ Link๊ฐ ๋ธ๋ผ์ฐ์ ์ ํ๋ฉด์ ๋ํ๋ ๋๋ง๋ค, ์ฌ์ฉ์๊ฐ ๋งํฌ๋ฅผ ํด๋ฆญํ๊ธฐ ์ ์ Next.js๊ฐ ๋ฐฑ๊ทธ๋ผ์ด๋์์ ์ฐ๊ฒฐ๋ ํ์ด์ง ์ฝ๋๋ฅผ ๋ฏธ๋ฆฌ ๋ก๋ํ๋ฏ๋ก ํ์ด์ง ์ ํ์ด ๊ฑฐ์ ์ฆ๊ฐ์ ์ผ๋ก ์ด๋ฃจ์ด์ง๋ค.
router.prefetch์ ์ด๋ํ๊ณ ์ ํ๋ url์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธฐ๋ฉด ๋๋ค. โ json๊ณผ js ํ์ผ์ prefetchํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
prefetch๋ฅผ ์๋์ผ๋ก ํด์ฃผ์ง ์๊ธฐ์ ํน๋ณํ ๊ฒฝ์ฐ๊ฐ ์๋๋ผ๋ฉด next/link๋ฅผ ์ฌ์ฉํ๋ ๊ฒ์ ๊ถ์ฅ
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
export default function Links() {
const router = useRouter();
useEffect(() => {
router.prefetch('/section1/getStaticProps');
}, [router]);
return (
<main>
<h1>Links</h1>
<button
onClick={() => {
router.push('/section1/getStaticProps');
}}
>
/getStaticProps
</button>
</main>
);
}
import Link from 'next/link';
export default function Links() {
return (
<main>
<h1>Links</h1>
<Link href='/section1/getStaticProps'>/getStaticProps</Link>
</main>
);
}
Next.js์์๋ ์ต์ด๋ก ์คํํ์ ๋ ํด๋น ํ์ด์ง์ HTML์ ๋ถ๋ฌ์จ๋ค.
ํ์ฌ๋ linkํ์ด์ง์ด๊ธฐ ๋๋ฌธ์ ๋งํฌํ์ด์ง์ ํด๋นํ๋ HTML ํ์ผ์ ๋ฐ์์จ ๊ฒ์ ํ์ธํ ์ ์๋ค.
ํ์ง๋ง ํ์ด์ง๋ฅผ ์ด๋ํ ๋ ์ถ๊ฐ์ ์ธ HTML์ ๋ฐ์์ค์ง ์๋๋ค. ๊ทธ๋ฆฌ๊ณ ๋คํธ์ํฌ๋ฅผ ํ์ธํ๋ฉด getStaticProps ํ์ด์ง์ ๊ดํ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ง ๊ฐ์ ธ์จ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฆ ์ต์ด ์คํ์ SSG๋ก ์คํ๋์ง๋ง ํ์ด์ง๋ฅผ ๋ผ์ฐํ ํ ๋๋ CSR๋ฐฉ์์ผ๋ก ๋น ๋ฅด๊ฒ ์ด๋ํ๋ค๋ ๊ฒ์ด๋ค.
๋ฐ๋๋ก getStaticPropsํ์ด์ง์์ ์๋ก๊ณ ์นจํ๋ฉด getStaticProps์ ํด๋นํ๋ HTML์ ๋ฐ์์ค๊ณ ๋ค๋ก ๊ฐ๊ธฐ๋ฅผ ๋๋ฌ๋ linksํ์ด์ง์ ํด๋นํ๋ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ง ๊ฐ์ ธ์ค๊ณ HTML ๋ฌธ์๋ ๋ฐ๋ก ๋ถ๋ฌ์ค์ง ์๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ด๋ ๊ฒ SSG์ CSR์ ๊ฒฐํฉํ ๋ผ์ฐํ ์ ํ ์ ์๋ ๊ฒ์ next/lnk๋๋ถ์ด๋ค.
๋น๊ต๋ฅผ ์ํด ์ผ๋ฐ์ ์ธ aํ๊ทธ๋ฅผ ์ด์ฉํ์!
์ด๋ ๊ฒ a tag๋ก ๋ฐ๋๊ฒ ๋๋ฉด ์๊น์ ๋ค๋ฅด๊ฒ jsonํ์ผ๋ ์๊ณ getStaticProps์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๋ ์๋ค.
๊ทธ๋ฆฌ๊ณ ๋งํฌ๋ฅผ ํตํด ์ด๋ํ๋ฉด
์๊น์ ๋ฌ๋ฆฌ getStaticProps๋ฅผ ์๋กญ๊ฒ HTML๋ก ๋ฐ์์ค๋ ๊ฒ์ ํ์ธํ ์ ์๋ค.
์ฆ CSR์ด ์๋๊ธฐ ๋๋ฌธ์, ๋งค๋ฒ ํ์ด์ง๋ฅผ ์ด๋ํ ๋๋ง๋ค HTMLํ์ผ์ ๋ฐ์์์ผ ํ๋ค.
๋ฐ๋๋ก next/link๋ฅผ ์ฌ์ฉํ๋ฉด ํด๋น ํ์ด์ง์ ๋ํ ์ ๋ณด๋ฅผ ์ด๋ฏธ js ํ์ผ๋ก ๊ฐ์ง๊ณ ์๋ค. ๊ทธ๋์ CSR๋ฐฉ์์ผ๋ก DOM์ ๋ ๋๋งํ ์ ์๋ ๊ฒ์ด๋ค.
์ถ๊ฐ๋ก jsonํ์ผ์ ๋ณด๋ฉด pageProps๋ผ๋ ๊ณณ์ data๊ฐ ๋ค์ด์์์ ํ์ธํ ์ ์๋ค.
data์ 0.29๊ฐ ์ ์ฅ๋์ด ์๋๋ฐ, getStaticProps ํ์ด์ง๋ก ์ด๋ํ๋ฉด,
๊ทธ ํด๋น ๊ฐ์ด ๊ทธ๋๋ก ๋ ๋๋ง๋๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
์ฆ ์๋ฐ์คํฌ๋ฆฝํธ ํ์ผ๊ณผ json์ด ๊ฒฐํฉํ์ฌ ๋ฐ๋ก DOM์ ์ ๋ฐ์ดํธํ ์ ์๋ค๋ ๊ฒ์ด๋ค.
์ด๊ฒ์ CSR๊ณผ ๋๊ฐ์ ๋ฐฉ์์ผ๋ก ์๋ํ๋ค.
๋๋ฌธ์ ์ต์ด์ ํ ๋ฒ๋ง HTMLํ์ผ์ ๊ฐ์ ธ์ค๊ณ next/link๊ฐ ์๋ ๊ณณ์ ์๋ฐ์คํฌ๋ฆฝํธ์ jsonํ์ผ๋ก ํด๋น ํ์ด์ง์ ๋ํ ์ ๋ณด๋ฅผ ๋ฏธ๋ฆฌ ๊ฐ์ ธ์์ ๋น ๋ฅด๊ฒ CSR๋ฐฉ์์ผ๋ก ๋ผ์ฐํ ํ ์ ์๋ ๊ฒ์ด๋ค.
๊ทธ๋ฆฌ๊ณ ์๊น ํ์ธํ๋ฏ ํ์ด์ง๋ง๋ค์ HTML๋ ์ด๋ฏธ ํ๋ฆฌ๋ ๋๋ง๋์ด ์๊ธฐ ๋๋ฌธ์ SEO๋ ๋ฌธ์ ๊ฐ ์๋ค.
import { useRouter } from 'next/router'
export default function Links() {
const router = useRouter();
return (
<main>
<h1>Links</h1>
<button
onClick={() => {
router.push('/section1/getStaticProps');
}}
>
/getStaticProps
</button>
</main>
);
}
๋ฒํผ์ ๋๋ฅด๋ฉด js์ jsonํ์ผ์ด ๋ค์ด๋ก๋ ๋ฐ์์ง๋ฉด์ CSR๋ฐฉ์์ผ๋ก ๋ผ์ฐํ ๋๋ค.
์ด๋ ๊ฒ useRouter๋ next/link๋ฅผ ๋์ฒดํ ์ ์๋ค.
ํ์ง๋ง next/link์ ๋ค๋ฅด๊ฒ ๋ฒํผ์ด ๋ณด์ธ๋ค๊ณ ํด์ ๋ฐ๋ก js, jsonํ์ผ์ ๊ฐ์ ธ์ค์ง ์๋๋ค.
next/link์ฒ๋ผ ์๋์ผ๋ก prefetchํ๊ธฐ ์ํด์๋ ๊ฐ๋ฐ์๊ฐ ์ง์ ์ฝ๋๋ฅผ ๊ตฌํํด์ผ ํ๋ค.
import Link from 'next/link';
import { useRouter } from 'next/router';
import { useEffect } from 'react';
export default function Links() {
const router = useRouter();
useEffect(() => {
router.prefetch('/section1/getStaticProps');
}, [router]);
return (
<main>
<h1>Links</h1>
<button
onClick={() => {
router.push('/section1/getStaticProps');
}}
>
/getStaticProp
</button>
</main>
);
}
router.prefetch์ ์ด๋ํ๊ณ ์ ํ๋ url์ ํ๋ผ๋ฏธํฐ๋ก ๋๊ธฐ๋ฉด ๋๋ค.
๊ทธ๋ฆฌ๊ณ ๋ค์ ์คํํ๋ฉด ์ด์ ๋ json๊ณผ jsํ์ผ์ prefetchํ๋ ๊ฒ์ ๋ณผ ์ ์๋ค.
<a>
ํ๊ทธ๋ฅผ ์์ ํ ๋์ฒดํ ์ ์๊ธฐ์ ์น์ฌ์ดํธ๊ฐ ํฌ๋กค๋ง ๋์ด SEO์ ์ ๋ฆฌํ๋ค.<a>
ํ๊ทธ๋ฅผ ๋ง๋ค์ง ์๊ธฐ ๋๋ฌธ์ ๊ฒ์์์ง ์ต์ ํ๋ฅผ ์ ๊ฒฝ์ฐ๊ณ ์๋ค๋ฉด ํด๋น ๋งํฌ๋ ํฌ๋กค๋ง๋์ง ์์