컨텐츠로 건너뛰기

요청 시 렌더링

Astro 프로젝트 코드는 웹에서 표시되기 위해 HTML로 렌더링되어야 합니다.

기본적으로 Astro 페이지, 경로 및 API 엔드포인트는 빌드 시점에 정적 페이지로 미리 렌더링됩니다. 하지만 경로가 요청될 때 일부 또는 모든 경로를 서버에서 필요에 따라 렌더링하도록 선택할 수 있습니다.

필요에 따라 렌더링되는 페이지와 경로는 방문할 때마다 생성되며 각 사용자에 맞게 설정될 수 있습니다. 예를 들어, 요청 시 렌더링되는 페이지는 로그인한 사용자의 계정 정보를 보여주거나 전체 사이트를 다시 빌드하지 않고도 새로 업데이트된 데이터를 표시할 수 있습니다.

요청 시점에 서버에서 필요에 따라 렌더링하는 것을 서버 측 렌더링(SSR) 이라고도 합니다.

페이지를 필요에 따라 렌더링하려면 어댑터를 추가해야 합니다. 각 어댑터를 통해 Astro는 특정 런타임에서 프로젝트를 실행하는 스크립트를 출력할 수 있습니다: 런타임은 페이지가 요청될 때 서버에서 페이지를 생성하는 코드를 실행하는 환경입니다(예: Netlify, Cloudflare).

사이트가 완전히 정적이고 페이지를 필요에 따라 렌더링하지 않더라도 어댑터를 추가하고 싶을 수 있습니다. 예를 들어, Netlify 어댑터는 Netlify의 이미지 CDN을 활성화하고, 서버 아일랜드는 컴포넌트에서 server:defer를 사용하기 위해 어댑터가 설치되어 있어야 합니다.

SSR 어댑터

Astro는 Node.js, Netlify, Vercel, Cloudflare를 위한 공식 어댑터를 관리합니다. 공식 및 커뮤니티 어댑터는 Astro 통합 디렉터리에서 찾을 수 있습니다. 배포 환경에 맞는 것을 선택하세요.

Astro가 관리하는 공식 어댑터 통합은 다음 astro add 명령으로 추가할 수 있습니다. 이 명령은 어댑터를 설치하고 astro.config.mjs 파일에 적절한 변경사항을 한 번에 적용합니다.

예를 들어, Netlify 어댑터를 설치하려면 다음을 실행하세요:

터미널 창
npx astro add netlify

NPM 패키지를 설치하여 어댑터를 수동으로 추가할 수도 있습니다(예: @astrojs/netlify). 그리고 astro.config.mjs를 직접 업데이트합니다.

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

요청 시 렌더링 활성화

섹션 제목: 요청 시 렌더링 활성화

기본적으로 전체 Astro 사이트는 미리 렌더링되며, 정적 HTML 페이지가 브라우저로 전송됩니다. 하지만 서버 렌더링이 필요한 모든 경로에서 사전 렌더링을 하지 않도록 선택할 수 있습니다. 예를 들어, 쿠키를 확인하고 개인화된 콘텐츠를 표시하는 페이지가 있습니다.

먼저, Astro 프로젝트에서 요청 시 서버 렌더링을 활성화하기 위해 서버 런타임용 어댑터 통합을 추가하세요.

그런 다음 요청 시 렌더링하려는 개별 페이지나 엔드포인트 상단에 export const prerender = false를 추가하세요. 사이트의 나머지 부분은 정적으로 유지됩니다:

src/pages/page-rendered-on-demand.astro
---
export const prerender = false
---
<html>
<!--
이 콘텐츠는 필요할 때 서버에서 렌더링됩니다!
서버 런타임용 어댑터 통합만 추가하세요!
다른 모든 페이지는 빌드 시점에 정적으로 생성됩니다!
-->
<html>

다음 예시는 엔드포인트가 호출될 때마다 임의의 숫자를 표시하기 위해 미리 렌더링하지 않도록 설정하는 것을 보여줍니다:

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

매우 동적인 앱의 경우, 어댑터를 추가한 후 빌드 출력 구성을 output: 'server'로 설정하여 기본적으로 모든 페이지를 서버에서 렌더링할 수 있습니다. 이는 모든 페이지에서 미리 렌더링하지 않도록 설정하는 것과 동일합니다.

그런 다음 필요한 경우 개인정보 보호정책이나 소개 페이지와 같이 서버 실행이 필요하지 않은 개별 페이지를 미리 렌더링하도록 선택할 수 있습니다.

src/pages/about-my-app.astro
---
export const prerender = true
---
<html>
<!--
`output: 'server'`가 구성되어 있지만 이 페이지는 정적입니다!
사이트의 나머지 부분은 요청 시 렌더링됩니다!
-->
<html>

정적 페이지나 엔드포인트를 미리 렌더링하려면 페이지나 경로에 export const prerender = true를 추가하세요:

src/pages/myendpoint.js
export const prerender = true;
export async function GET() {
return new Response(
JSON.stringify({
message: `This is my static endpoint`,
}),
);
}
구성 참조에서 output 설정에 대해 자세히 알아보세요.

HTML 스트리밍을 사용하면 문서가 청크로 나뉘어 순서대로 네트워크를 통해 전송되고 해당 순서대로 페이지에 렌더링됩니다. Astro는 요청 시 렌더링에서 HTML 스트리밍을 사용하여 각 컴포넌트를 렌더링할 때마다 브라우저로 전송합니다. 이를 통해 사용자가 HTML을 최대한 빨리 볼 수 있지만, 네트워크 상태로 인해 큰 문서가 느리게 다운로드될 수 있고 데이터 가져오기를 기다리는 동안 페이지 렌더링이 차단될 수 있습니다.

요청 시 렌더링되는 페이지나 API 엔드포인트에서는 쿠키를 확인, 설정, 가져오기 및 삭제할 수 있습니다.

아래 예시는 페이지 조회수 카운터를 위한 쿠키 값을 업데이트합니다:

src/pages/index.astro
---
export const prerender = false; // 'server' 모드에서는 필요하지 않습니다.
let counter = 0
if (Astro.cookies.has('counter')) {
const cookie = Astro.cookies.get('counter')
const value = cookie?.number()
if (value !== undefined && !isNaN(value)) counter = value + 1
}
Astro.cookies.set('counter', String(counter))
---
<html>
<h1>Counter = {counter}</h1>
</html>

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

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

아래 예시는 제품이 존재하지 않을 때 제품 페이지의 응답 상태와 상태 텍스트를 설정합니다:

src/pages/product/[id].astro
---
export const prerender = false; // 'server' 모드에서는 필요하지 않습니다.
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
---
export const prerender = false; // 'server' 모드에서는 필요하지 않습니다.
Astro.response.headers.set('Cache-Control', 'public, max-age=3600');
---
<html>
<!-- 페이지 -->
</html>

요청 시 렌더링되는 모든 페이지에서 수동으로 또는 Astro.redirect를 사용하여 Response 객체를 직접 반환할 수 있습니다.

아래 예시는 동적 페이지에서 데이터베이스의 ID를 조회하고, 제품이 존재하지 않으면 404를 반환하거나 제품을 더 이상 사용할 수 없는 경우 사용자를 다른 페이지로 리디렉션하거나 제품을 표시합니다:

src/pages/product/[id].astro
---
export const prerender = false; // 'server' 모드에서는 필요하지 않습니다.
import { getProduct } from '../api';
const product = await getProduct(Astro.params.id);
// 제품을 찾을 수 없는 경우
if (!product) {
return new Response(null, {
status: 404,
statusText: 'Not found'
});
}
// 제품을 사용할 수 없는 경우
if (!product.isAvailable) {
return Astro.redirect("/products", 301);
}
---
<html>
<!-- 페이지 -->
</html>

Astro.request는 표준 Request 객체입니다. url, headers, method, 그리고 요청의 본문까지 얻는 데 사용할 수 있습니다.

정적으로 생성되지 않은 페이지에서 이 객체를 통해 추가 정보에 접근할 수 있습니다.

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

src/pages/index.astro
---
export const prerender = false; // 'server' 모드에서는 필요하지 않습니다.
const cookie = Astro.request.headers.get('cookie');
// ...
---
<html>
<!-- 페이지 -->
</html>

Astro.request.method를 통해 요청에 사용된 HTTP 메서드를 확인할 수 있습니다. 이는 브라우저의 Request.method와 같이 작동합니다. 요청에 사용된 HTTP 메서드의 문자열 표현을 반환합니다.

src/pages/index.astro
---
export const prerender = false; // 'server' 모드에서는 필요하지 않습니다.
console.log(Astro.request.method) // GET (브라우저에서 탐색했을 때)
---

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

API 라우트라고도 하는 서버 엔드포인트는 src/pages/ 폴더의 .js 또는 .ts 파일에서 내보내는 특별한 함수입니다. 필요에 따른 서버 측 렌더링의 강력한 기능인 API 라우트는 서버에서 안전하게 코드를 실행할 수 있습니다.

이 함수는 엔드포인트 컨텍스트를 받아서 Response를 반환합니다.

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

기여하기

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

GitHub Issue 생성

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

커뮤니티