Draft Mode

Statik oluşturma, sayfalarınız başsız bir CMS'den veri aldığında kullanışlıdır. Ancak, başsız CMS'nizde bir taslak yazarken ve taslağı hemen sayfanızda görüntülemek istediğinizde ideal değildir. Next.js'nin bu sayfaları derleme zamanı yerine istek zamanında oluşturmasını ve yayınlanan içerik yerine taslak içeriği getirmesini istersiniz. Next.js'in yalnızca bu özel durum için dinamik oluşturmaya geçmesini istersiniz.

Next.js, bu sorunu çözen Taslak Modu adlı bir özelliğe sahiptir. İşte nasıl kullanılacağına dair talimatlar.

Step 1: Create and access the Route Handler

İlk olarak, bir Rota İşleyicisi oluşturun. Herhangi bir isme sahip olabilir - örn. app/api/draft/route.ts

Ardından, draftMode adresini next/headers adresinden içe aktarın ve enable() yöntemini çağırın.

app/api/draft/route.ts
// route handler enabling draft mode
import { draftMode } from 'next/headers'
 
export async function GET(request: Request) {
  draftMode().enable()
  return new Response('Draft mode is enabled')
}

Bu, taslak modunu etkinleştirmek için bir çerez ayarlayacaktır. Bu çerezi içeren sonraki istekler, statik olarak oluşturulan sayfaların davranışını değiştirerek Taslak Modunu tetikleyecektir (bu konuda daha sonra daha fazla bilgi verilecektir).

Bunu /api/draft adresini ziyaret ederek ve tarayıcınızın geliştirici araçlarına bakarak manuel olarak test edebilirsiniz. __prerender_bypass adında bir çerez içeren Set-Cookie yanıt başlığına dikkat edin.

Securely accessing it from your Headless CMS

Pratikte, bu Rota İşleyiciyi başsız CMS'nizden güvenli bir şekilde çağırmak istersiniz. Belirli adımlar hangi başsız CMS'yi kullandığınıza bağlı olarak değişecektir, ancak burada atabileceğiniz bazı genel adımlar vardır.

Bu adımlar, kullandığınız başsız CMS'nin özel taslak URL'leri ayarlamayı desteklediğini varsaymaktadır. Desteklemiyorsa, taslak URL'lerinizi güvence altına almak için bu yöntemi yine de kullanabilirsiniz, ancak taslak URL'yi manuel olarak oluşturmanız ve erişmeniz gerekir.

İlk olarak, seçtiğiniz bir token oluşturucuyu kullanarak gizli bir token dizesi oluşturmalısınız. Bu sır yalnızca Next.js uygulamanız ve başsız CMS'niz tarafından bilinecektir. Bu sır, CMS'nize erişimi olmayan kişilerin taslak URL'lere erişmesini engeller.

İkinci olarak, başsız CMS'niz özel taslak URL'lerin ayarlanmasını destekliyorsa, taslak URL olarak aşağıdakileri belirtin. Bu, Rota İşleyicinizin şu adreste bulunduğunu varsayar app/api/draft/route.ts

Terminal
https://<your-site>/api/draft?secret=<token>&slug=<path>

Başlıksız CMS'niz taslak URL'ye bir değişken eklemenize izin verebilir, böylece <path> CMS'nin verilerine göre dinamik olarak şu şekilde ayarlanabilir: &slug=/posts/{entry.fields.slug}

Son olarak, Rota İşleyicide:

app/api/draft/route.ts
// route handler with secret and slug
import { draftMode } from 'next/headers'
import { redirect } from 'next/navigation'
 
export async function GET(request: Request) {
  // Parse query string parameters
  const { searchParams } = new URL(request.url)
  const secret = searchParams.get('secret')
  const slug = searchParams.get('slug')
 
  // Check the secret and next parameters
  // This secret should only be known to this route handler and the CMS
  if (secret !== 'MY_SECRET_TOKEN' || !slug) {
    return new Response('Invalid token', { status: 401 })
  }
 
  // Fetch the headless CMS to check if the provided `slug` exists
  // getPostBySlug would implement the required fetching logic to the headless CMS
  const post = await getPostBySlug(slug)
 
  // If the slug doesn't exist prevent draft mode from being enabled
  if (!post) {
    return new Response('Invalid slug', { status: 401 })
  }
 
  // Enable Draft Mode by setting the cookie
  draftMode().enable()
 
  // Redirect to the path from the fetched post
  // We don't redirect to searchParams.slug as that might lead to open redirect vulnerabilities
  redirect(post.slug)
}

Başarılı olursa, tarayıcı taslak modu çerezi ile görüntülemek istediğiniz yola yönlendirilecektir.

Step 2: Update page

Bir sonraki adım, draftMode().isEnabled değerini kontrol etmek için sayfanızı güncellemektir.

Çerezin ayarlandığı bir sayfayı talep ederseniz, veriler istek zamanında (derleme zamanı yerine) getirilecektir.

Ayrıca, isEnabled adresinin değeri true olacaktır.

app/page.tsx
// page that fetches data
import { draftMode } from 'next/headers'
 
async function getData() {
  const { isEnabled } = draftMode()
 
  const url = isEnabled
    ? 'https://draft.example.com'
    : 'https://production.example.com'
 
  const res = await fetch(url)
 
  return res.json()
}
 
export default async function Page() {
  const { title, desc } = await getData()
 
  return (
    <main>
      <h1>{title}</h1>
      <p>{desc}</p>
    </main>
  )
}

İşte bu kadar! Taslak Rota İşleyicisine ( secret ve slug ile) headless CMS'nizden veya manuel olarak erişirseniz, artık taslak içeriği görebilmeniz gerekir. Ve taslağınızı yayınlamadan güncellerseniz, taslağı görüntüleyebilmeniz gerekir.

Bunu headless CMS'nizde taslak URL'si olarak ayarlayın veya manuel olarak erişin ve taslağı görebilmeniz gerekir.

Terminal
https://<your-site>/api/draft?secret=<token>&slug=<path>

More Details

Varsayılan olarak, Taslak Modu oturumu tarayıcı kapatıldığında sona erer.

Taslak Modu çerezini manuel olarak temizlemek için draftMode().disable() adresini çağıran bir Rota İşleyicisi oluşturun:

app/api/disable-draft/route.ts
import { draftMode } from 'next/headers'
 
export async function GET(request: Request) {
  draftMode().disable()
  return new Response('Draft mode is disabled')
}

Ardından, Rota İşleyicisini çağırmak için /api/disable-draft adresine bir istek gönderin. Bu rotayı kullanarak çağırıyorsanız next/linkçerezinin yanlışlıkla silinmesini önlemek için prefetch={false} adresini geçmelisiniz.

Unique per next build

next build adresini her çalıştırdığınızda yeni bir bypass çerez değeri oluşturulacaktır.

Bu, bypass çerezinin tahmin edilememesini sağlar.

Bilmekte fayda var: Taslak Modunu HTTP üzerinden yerel olarak test etmek için tarayıcınızın üçüncü taraf çerezlerine ve yerel depolama erişimine izin vermesi gerekir.