콘텐츠로 이동

요청 시 렌더링

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

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

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

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

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

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

어댑터

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를 반환합니다.

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

기여하기 커뮤니티 후원하기