컨텐츠로 건너뛰기

주문형 렌더링 어댑터

Astro를 사용하면 페이지와 엔드포인트 전체 또는 일부에 대해 주문형 렌더링을 선택할 수 있습니다. 이는 서버 측 렌더링(SSR) 이라고도 알려져 있으며, 요청 시 서버에서 HTML 페이지를 생성하여 클라이언트에 보냅니다. 어댑터는 서버에서 프로젝트를 실행하고 이러한 요청을 처리하는 데 사용됩니다.

이 주문형 렌더링을 통해 다음을 수행할 수 있습니다.

  • 앱에서 로그인 상태에 대한 세션을 구현합니다.
  • fetch()를 사용하여 동적으로 호출되는 API에서 데이터를 렌더링합니다.
  • 어댑터를 사용하여 사이트를 호스트에 배포합니다.

다음이 필요한 경우 Astro 프로젝트에서 주문형 서버 렌더링을 활성화하는 것이 좋습니다.

  • API 엔드포인트: 중요한 데이터를 클라이언트에게 숨기면서 데이터베이스 액세스, 인증, 권한 부여와 같은 작업을 위한 API 엔드포인트로 작동하는 특정 페이지를 만듭니다.

  • 보호된 페이지: 서버에서 사용자 액세스를 처리하여 사용자 권한에 따라 페이지에 대한 액세스를 제한합니다.

  • 자주 변경되는 콘텐츠: 사이트를 다시 정적으로 빌드하지 않고도 개별 페이지를 생성할 수 있습니다. 이는 페이지 내용이 자주 업데이트되는 경우 유용합니다.

Astro는 Node.js, Vercel, Netlify, Cloudflare용 공식 어댑터를 유지 관리합니다.

통합 디렉터리에서 커뮤니티에서 관리하는 더 많은 어댑터 (예: Deno, SST, AWS)를 찾아보세요.

SSR 어댑터

주문형 서버 렌더링 활성화

섹션 제목: 주문형 서버 렌더링 활성화

Astro의 두 주문형 렌더링 출력 모드 (serverhybrid)를 사용하면 완전히 동적인 앱을 사용하든, 특정 경로에 대해서만 주문형 렌더링이 필요한 대부분이 정적인 사이트를 사용하든, 가능하면 개별 경로를 미리 렌더링하여 정적 사이트의 성능을 활용할 수 있습니다.

프로젝트에서 사용할 항목을 결정하려면 페이지와 경로의 대부분이 렌더링되는 방식을 나타내는 output 옵션을 선택하세요.

  • output: 'server': 기본적으로 주문형으로 렌더링됩니다. 요청 시 사이트나 앱의 대부분 또는 전부를 서버 렌더링해야 하는 경우 이 방법을 사용하세요. 모든 개별 페이지 또는 엔드포인트는 사전 렌더링을 선택할 수 있습니다.
  • output: 'hybrid': 기본적으로 HTML로 사전 렌더링됩니다. 대부분의 사이트가 정적이어야 할 때 이 옵션을 사용하세요. 모든 개별 페이지 또는 엔드포인트는 사전 렌더링을 거부할 수 있습니다.

서버는 요청 시 최소한 일부 페이지를 생성해야 하기 때문에 이 두 모드 모두 서버 기능을 수행하려면 어댑터 추가가 필요합니다.

server 또는 hybrid 모드로 프로젝트를 배포하려면 어댑터를 추가해야 합니다. 이는 두 모드 모두 서버 런타임, 즉 요청 시 페이지를 생성하기 위해 서버에서 코드를 실행하는 환경이 필요하기 때문입니다. 각 어댑터를 사용하면 Astro는 Vercel, Netlify, Cloudflare와 같은 특정 런타임에서 프로젝트를 실행하는 스크립트를 출력할 수 있습니다.

통합 디렉터리에서 공식 어댑터와 커뮤니티 어댑터를 모두 찾을 수 있습니다. 배포 환경에 해당하는 것을 선택하세요.

다음 astro add 명령을 사용하여 Astro에서 유지관리하는 공식 어댑터를 추가할 수 있습니다. 그러면 어댑터가 설치되고 astro.config.mjs 파일이 한 번에 적절하게 변경됩니다.

예를 들어 Vercel 어댑터를 설치하려면 다음을 실행합니다.

Terminal window
npx astro add vercel

패키지를 설치하고 astro.config.mjs 파일을 직접 업데이트하여 수동으로 어댑터를 추가할 수도 있습니다.

예를 들어 Vercel 어댑터를 수동으로 설치하려면 다음을 수행하세요.

  1. 원하는 패키지 관리자를 사용하여 프로젝트 종속성에 어댑터를 설치합니다.

    Terminal window
    npm install @astrojs/vercel
  2. 원하는 output 모드와 함께 astro.config.mjs 파일의 가져오기 및 기본 내보내기에 어댑터를 추가합니다.

    astro.config.mjs
    import { defineConfig } from 'astro/config';
    import vercel from '@astrojs/vercel/serverless';
    export default defineConfig({
    output: 'server',
    adapter: vercel(),
    });

    어댑터마다 구성 설정이 다를 수도 있습니다. 각 어댑터의 문서를 읽고 astro.config.mjs 파일에서 선택한 어댑터에 필요한 구성 옵션을 적용하세요.

주문형 렌더링을 활성화하려면 output 구성을 두 가지 서버 렌더링 모드 중 하나로 업데이트해야 합니다.

예를 들어 기본적으로 모든 페이지가 요청 시 렌더링되는 매우 동적인 앱을 구성하려면 Astro 구성에 output: 'server'를 추가하세요.

astro.config.mjs
import { defineConfig } from 'astro/config';
import node from "@astrojs/node";
export default defineConfig({
output: 'server',
adapter: node({
mode: "standalone"
})
});

server 모드에서 사전 렌더링 선택

섹션 제목: server 모드에서 사전 렌더링 선택

output: server를 사용하여 대부분이 서버 렌더링된 앱의 경우, 정적 페이지 또는 엔드포인트를 사전 렌더링하려면 모든 페이지 또는 경로에 export const prerender = true를 추가하세요.

src/pages/mypage.astro
---
export const prerender = true;
// ...
---
<html>
<!-- 정적, 사전 렌더링된 페이지는 여기에 있습니다... -->
</html>
src/pages/mypage.mdx
---
layout: '../layouts/markdown.astro'
title: '내 페이지'
---
export const prerender = true;
# 이것은 내 정적, 사전 렌더링된 페이지입니다.
src/pages/myendpoint.js
export const prerender = true;
export async function GET() {
return new Response(
JSON.stringify({
message: `이것은 내 정적 엔드포인트입니다.`,
}),
);
}

hybrid 모드에서 사전 렌더링 선택 해제

섹션 제목: hybrid 모드에서 사전 렌더링 선택 해제

output: hybrid로 구성된 대부분이 정적으로 구성된 사이트의 경우, 요청 시 서버 렌더링해야 하는 모든 파일에 export const prerender = false를 추가하세요.

src/pages/randomnumber.js
export const prerender = false;
export async function GET() {
let number = Math.random();
return new Response(
JSON.stringify({
number,
message: `임의의 숫자: ${number}`,
}),
);
}

HTML 스트리밍을 사용하면 문서가 여러 개의 청크로 분할되어 네트워크를 통해 순서대로 전송되고 해당 순서대로 페이지에 렌더링됩니다. server 또는 hybrid 모드에서 Astro는 HTML 스트리밍을 사용하여 각 컴포넌트를 렌더링할 때 브라우저에 보냅니다. 네트워크 상태로 인해 큰 문서가 느리게 다운로드될 수 있고 데이터 가져오기를 기다리면 페이지 렌더링이 차단될 수 있지만 이렇게 하면 사용자가 가능한 한 빨리 HTML을 볼 수 있습니다.

serverhybrid 모드에서는 페이지 또는 API 엔드포인트가 쿠키를 확인, 설정, 가져오기 및 삭제할 수 있습니다.

아래 예시에서는 페이지 조회수 카운터의 쿠키 값을 업데이트합니다.

src/pages/index.astro
---
let counter = 0
if (Astro.cookies.has("counter")) {
const cookie = Astro.cookies.get("counter")
counter = cookie.number() + 1
}
Astro.cookies.set("counter",counter)
---
<html>
<h1>카운터 = {counter}</h1>
</html>

API 참조에서 Astro.cookiesAstroCookie 타입에 대한 자세한 내용을 확인하세요.

Astro.response는 표준 ResponseInit 객체입니다. 응답 상태와 헤더를 설정하는 데 사용할 수 있습니다.

아래 예시에서는 제품이 존재하지 않는 경우 제품 목록 페이지에 대한 응답 상태 및 상태 텍스트를 설정합니다.

src/pages/my-product.astro
---
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// 제품을 찾을 수 없는 경우
if (!product) {
Astro.response.status = 404;
Astro.response.statusText = 'Not found';
}
---
<html>
<!-- 페이지 -->
</html>

Astro.response.headers 객체를 사용하여 헤더를 설정할 수 있습니다.

src/pages/index.astro
---
Astro.response.headers.set('Cache-Control', 'public, max-age=3600');
---
<html>
<!-- 페이지 -->
</html>

주문형 렌더링을 사용하면 모든 페이지에서 직접 Response 객체를 반환할 수도 있습니다.

아래 예시는 데이터베이스에서 id를 조회한 후 동적 페이지에 404를 반환합니다.

src/pages/[id].astro
---
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// product를 찾지 못함
if (!product) {
return new Response(null, {
status: 404,
statusText: '찾을 수 없음'
});
}
---
<html>
<!-- 페이지... -->
</html>

Astro.request는 표준 Request 객체입니다. url, headers, method 및 요청 본문을 가져오는 데 사용할 수 있습니다.

serverhybrid 모드 모두에서 정적으로 생성되지 않은 페이지에 대해 이 객체의 추가 정보에 액세스할 수 있습니다.

요청 헤더는 Astro.request.headers에서 확인할 수 있습니다. 이는 브라우저의 Request.headers처럼 작동합니다. 쿠키와 같은 헤더를 검색할 수 있는 Headers 객체입니다.

src/pages/index.astro
---
const cookie = Astro.request.headers.get('cookie');
// ...
---
<html>
<!-- 페이지... -->
</html>

요청에 사용된 HTTP 메서드는 Astro.request.method로 제공됩니다. 이는 브라우저의 Request.method처럼 작동합니다. 요청에 사용된 HTTP 메서드의 문자열 표현을 반환합니다.

src/pages/index.astro
---
console.log(Astro.request.method) // GET (브라우저에서 탐색할 때)
---

API 참조에서 Astro.request에 대한 자세한 내용을 확인하세요.

API 경로라고도 알려진 서버 엔드포인트는 src/pages/ 폴더 내 .js 또는 .ts 파일에서 내보낸 특수 기능입니다. 주문형 서버 측 렌더링의 강력한 기능인 API 경로는 서버에서 코드를 안전하게 실행할 수 있습니다.

이 함수는 엔드포인트 컨텍스트를 취하고 Response를 반환합니다.

자세한 내용은 엔드포인트 안내서를 참조하세요.

기여하기

여러분의 생각을 들려주세요!

GitHub Issue 생성

우리에게 가장 빨리 문제를 알려줄 수 있어요.

커뮤니티