ํฐ์คํ ๋ฆฌ ๋ทฐ
๐ Next.js Draft Mode ์ฌ์ฉ ๊ฐ์ด๋
Next.js์ Draft Mode๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์ํ๋ก ์ฝํ
์ธ ๋ฅผ ํ์ธํ ์ ์๋ ๊ธฐ๋ฅ์
๋๋ค.
Draft Mode๋ฅผ ์ฌ์ฉํ๋ฉด CMS์ ์ฐ๋ํ์ฌ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํ์ด์ง๋ฅผ ์ฝ๊ฒ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
์ด ๊ฐ์ด๋๋ฅผ ํตํด Draft Mode ์ค์ ๊ณผ ํ์ฉ ๋ฐฉ๋ฒ์ ๋จ๊ณ๋ณ๋ก ์์๋ณด๊ฒ ์ต๋๋ค.
โ 1. Draft Mode๋?
Draft Mode๋ ์ ์ ํ์ด์ง๋ฅผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ชจ๋๋ก ์ ํํ์ฌ ์ฝํ
์ธ ๋ฅผ ์ค์๊ฐ์ผ๋ก ํ์ธํ ์ ์๋ ๊ธฐ๋ฅ์
๋๋ค.
์ ์ ์ฌ์ดํธ ์์ฑ(SSG)์์ ์ค์๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ์ ๊ณตํ ๋ ์ ์ฉํฉ๋๋ค.
โ 2. Draft Mode ํ์ฑํ
์ค์ ๋ฐฉ๋ฒ
Draft Mode๋ฅผ ํ์ฑํํ๊ธฐ ์ํด Next.js์ res ๊ฐ์ฒด๋ฅผ ์ฌ์ฉํฉ๋๋ค.
๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ชจ๋๋ฅผ ํ์ฑํํ๋ API๋ฅผ ์์ฑํฉ๋๋ค.
// app/api/draft/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const response = NextResponse.json({ message: 'Draft mode ํ์ฑํ' });
response.cookies.set('NEXT_PUBLIC_DRAFT_MODE', 'true', {
httpOnly: true,
path: '/',
});
return response;
}
๋นํ์ฑํ API
// app/api/exit-draft/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const response = NextResponse.json({ message: 'Draft mode ๋นํ์ฑํ' });
response.cookies.set('NEXT_PUBLIC_DRAFT_MODE', '', {
httpOnly: true,
path: '/',
maxAge: -1,
});
return response;
}
โ 3. Draft Mode ํ์ด์ง ์ฒ๋ฆฌ
ํ์ด์ง ๋ด์์ Draft Mode ์ํ ํ์ธ
// app/page.tsx
import { cookies } from 'next/headers';
export default function HomePage() {
const draftMode = cookies().get('NEXT_PUBLIC_DRAFT_MODE');
if (draftMode?.value) {
return <h1>๐ Draft Mode ํ์ฑํ ์ค</h1>;
}
return <h1>์ ์ ๋ชจ๋ ํ์ด์ง</h1>;
}
ํ์ฑํ ๋ฐ ๋นํ์ฑํ ๋ฒํผ
// app/components/DraftToggle.tsx
export default function DraftToggle() {
const enableDraft = async () => {
await fetch('/api/draft');
window.location.reload();
};
const disableDraft = async () => {
await fetch('/api/exit-draft');
window.location.reload();
};
return (
<div>
<button onClick={enableDraft}>Draft ๋ชจ๋ ์ผ๊ธฐ</button>
<button onClick={disableDraft}>Draft ๋ชจ๋ ๋๊ธฐ</button>
</div>
);
}
โ 4. Draft Mode๋ฅผ ํ์ฉํ ์ค์๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ
CMS์ ์ฐ๊ฒฐํ์ฌ ์ค์๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ฅผ ๊ตฌ์ฑํ ์ ์์ต๋๋ค.
์: Sanity์ ์ฐ๋
- Sanity์์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ URL ์ค์ :
- /api/draft?slug=my-page ํํ๋ก ์ค์
- Next.js API์์ ์ฒ๋ฆฌ
// app/api/draft/route.ts
import { NextRequest, NextResponse } from 'next/server';
export async function GET(request: NextRequest) {
const { searchParams } = new URL(request.url);
const slug = searchParams.get('slug');
if (!slug) {
return NextResponse.json({ message: '์๋ชป๋ ์์ฒญ' }, { status: 400 });
}
const response = NextResponse.redirect(`/${slug}`);
response.cookies.set('NEXT_PUBLIC_DRAFT_MODE', 'true', {
httpOnly: true,
path: '/',
});
return response;
}
ํ์ด์ง์์ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํ์ธ
// app/[slug]/page.tsx
import { cookies } from 'next/headers';
export default function Page({ params }: { params: { slug: string } }) {
const draftMode = cookies().get('NEXT_PUBLIC_DRAFT_MODE');
return (
<div>
<h1>{params.slug} ํ์ด์ง</h1>
{draftMode?.value && <p>Draft ๋ชจ๋๊ฐ ํ์ฑํ๋์์ต๋๋ค.</p>}
</div>
);
}
โ 5. Draft Mode ์ฃผ์์ฌํญ
- SEO ์ ์: Draft Mode ํ์ด์ง๊ฐ ๊ฒ์์์ง์ ๋ ธ์ถ๋์ง ์๋๋ก ์ค์ ํ์
- ์บ์ฑ ๋ฌธ์ : ์บ์ ๋ฌดํจํ๋ฅผ ํตํด ์ต์ ์ฝํ ์ธ ๋ฅผ ๋ฏธ๋ฆฌ๋ณด๊ธฐ๋ก ์ ๊ณต
- ๋ณด์ ๊ณ ๋ ค: ๋ฌด๋ถ๋ณํ ํ์ฑํ๋ฅผ ๋ง๊ธฐ ์ํด ๊ด๋ฆฌ์ ์ ์ฉ์ผ๋ก ์ค์
โ 6. ๋ฐฐํฌ ์ ๊ณ ๋ ค์ฌํญ
Draft Mode๋ ๊ฐ๋ฐ ํ๊ฒฝ ๋๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ์๋ฒ์์๋ง ์ฌ์ฉํด์ผ ํฉ๋๋ค.
ํ๋ก๋์
ํ๊ฒฝ์์๋ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ชจ๋๊ฐ ๋
ธ์ถ๋์ง ์๋๋ก ์ฃผ์ํด์ผ ํฉ๋๋ค.
ํ๊ฒฝ ๋ณ์ ์ค์
NEXT_PUBLIC_DRAFT_MODE=false
์กฐ๊ฑด๋ถ ๋ ๋๋ง
if (process.env.NEXT_PUBLIC_DRAFT_MODE !== 'true') {
return <h1>Draft Mode ์ฌ์ฉ ๋ถ๊ฐ</h1>;
}
โ ์์ฝ
๊ธฐ๋ฅ ์ค๋ช
Draft Mode ํ์ฑํ | /api/draft ์๋ํฌ์ธํธ๋ฅผ ํตํด ํ์ฑํ |
Draft Mode ๋นํ์ฑํ | /api/exit-draft ์๋ํฌ์ธํธ๋ก ์ข ๋ฃ |
์ํ ํ์ธ ๋ฐ ๋ ๋๋ง | ์ฟ ํค๋ฅผ ํตํด ํ์ฌ ๋ชจ๋ ํ์ธ |
์ค์๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ ํ์ฉ | CMS ์ฐ๋ํ์ฌ ์ด์ ์ฝํ ์ธ ๋ฏธ๋ฆฌ๋ณด๊ธฐ |
๋ฐฐํฌ ํ๊ฒฝ ๊ณ ๋ ค์ฌํญ | ํ๋ก๋์ ์์ ํ์ฑํ๋์ง ์๋๋ก ์ค์ |
Next.js, Draft Mode, ์ค์๊ฐ ๋ฏธ๋ฆฌ๋ณด๊ธฐ, CMS ์ฐ๋, ์ฟ ํค ๊ด๋ฆฌ, API ์ค์ , ๊ฐ๋ฐ ํ๊ฒฝ, ๋ฏธ๋ฆฌ๋ณด๊ธฐ ๋ชจ๋, ์ฝํ ์ธ ๋ฏธ๋ฆฌ๋ณด๊ธฐ, SEO ๊ณ ๋ ค์ฌํญ
'framework > NextJS' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
๐ชฒ Next.js ๋๋ฒ๊น ๊ฐ์ด๋ (0) | 2025.05.13 |
---|---|
๐ ๏ธ Next.js์์ ์ปค์คํ ์๋ฒ(Custom Server) ๊ตฌ์ถํ๊ธฐ (0) | 2025.05.12 |
๐ NestJS ModuleRef โ ๋์ ๋ชจ๋ ์ธ์คํด์ค ์ฃผ์ ์์ ๊ฐ์ด๋ (0) | 2025.05.12 |
๐จ Next.js App Router์์ CSS-in-JS ์ฌ์ฉํ๊ธฐ (0) | 2025.05.09 |
๐ก๏ธ Next.js Content Security Policy(CSP) ์ค์ ๊ฐ์ด๋ (0) | 2025.05.09 |
- Total
- Today
- Yesterday
- github
- Webpack
- gatsbyjs
- ํ๋ก ํธ์๋๋ฉด์
- AI์ฑ๋ด
- LangChain
- Python
- seo ์ต์ ํ 10๊ฐ
- SEO์ต์ ํ
- Docker
- Next.js
- Ktor
- rag
- ๊ฐ๋ฐ๋ธ๋ก๊ทธ
- ํ์ด์ฌ ์๊ณ ๋ฆฌ์ฆ
- fastapi
- llm
- ๊ด๋ฆฌ์
- CI/CD
- ์น๊ฐ๋ฐ
- NestJS
- PostgreSQL
- ๋ฐฑ์๋๊ฐ๋ฐ
- App Router
- nodejs
- kotlin
- REACT
- Prisma
- ํ๋ก ํธ์๋
- nextJS
์ผ | ์ | ํ | ์ | ๋ชฉ | ๊ธ | ํ |
---|---|---|---|---|---|---|
1 | 2 | 3 | ||||
4 | 5 | 6 | 7 | 8 | 9 | 10 |
11 | 12 | 13 | 14 | 15 | 16 | 17 |
18 | 19 | 20 | 21 | 22 | 23 | 24 |
25 | 26 | 27 | 28 | 29 | 30 | 31 |