뷰 전환
뷰 전환은 웹사이트의 다른 뷰로 이동할 때 전환되는 애니메이션 효과를 의미합니다. 이는 방문자가 애플리케이션의 상태 또는 뷰 사이를 이동할 때 시각적 연속성을 유지하기 위해 선택할 수 있는 인기 디자인입니다.
Astro의 뷰 전환 및 클라이언트 측 라우팅 지원은 뷰 전환 브라우저 API를 기반으로 하며 다음을 포함합니다.
fade,slide및none과 같은 몇 가지 내장 애니메이션 옵션- 정방향 및 역방향 탐색 애니메이션 모두 지원
- 전환 애니메이션의 모든 측면을 완전히 사용자 정의하고 자신만의 애니메이션을 구축할 수 있는 기능
- 페이지 이동 시 현재 페이지의 HTML 요소를 다음 페이지로 전달하는 방법
- 페이지 링크가 아닌 링크에 대한 클라이언트 측 탐색을 방지하는 옵션
- 뷰 전환 API를 아직 지원하지 않는 브라우저에 대한 대체 동작 제어
prefers-reduced-motion자동 지원
기본적으로 모든 페이지는 일반적인 전체 페이지 브라우저 탐색을 사용합니다. 뷰 전환을 선택해야 페이지별 또는 사이트 전체에서 사용할 수 있습니다.
브라우저 네이티브 뷰 전환과 Astro의 <ClientRouter />의 차이점
섹션 제목: “브라우저 네이티브 뷰 전환과 Astro의 <ClientRouter />의 차이점”브라우저 네이티브 문서 간 뷰 전환은 Astro에서 다중 페이지 앱 (MPA)의 문서 탐색을 애니메이션화하는 데 사용될 수 있으며, 종종 단일 페이지 애플리케이션의 클라이언트 측 라우팅 경험을 제공합니다. 이는 다중 페이지 애플리케이션의 핵심 기능을 변경하지 않으며, 기존 스크립트에 영향을 주거나 페이지를 로드할 때 JavaScript를 추가하지 않습니다. 단지 애니메이션을 추가할 뿐입니다.
뷰 전환 API에서 아직 완벽하게 지원되지 않는 향상된 클라이언트 측 라우팅 및 뷰 전환 기능을 위해, Astro는 내장된 경량 컴포넌트를 제공하여 클라이언트 측 라우팅을 활성화하고 다중 페이지 앱을 부드러운 애니메이션을 사용하여 탐색하는 단일 페이지 앱으로 전환합니다.
이는 페이지 간에 상태를 공유하고 요소를 유지하는 것과 같은 몇 가지 이점을 제공하지만, 탐색 후 스크립트나 상태를 수동으로 다시 초기화해야 하는 것과 같은 몇 가지 단점도 존재합니다.
Astro의 내장 <ClientRouter /> 컴포넌트는 다음을 수행합니다.
- 페이지 탐색을 가로채고 이 프로세스에 상당한 제어를 제공합니다.
- 일부 뷰 전환 및 탐색 API 기능을 확장하고 향상시킵니다.
- 네이티브 브라우저 지원이 부족할 경우를 대비하여 대체 전략을 구성할 수 있습니다.
하지만 브라우저 API와 웹 표준이 발전함에 따라, 이러한 추가 기능을 위해 Astro의 <ClientRouter />를 사용하는 것은 점점 더 불필요해질 것입니다. 현재 브라우저 API의 상태를 지속적으로 살펴보며, 특정 기능을 사용하기 위해 여전히 Astro의 클라이언트 측 라우팅이 필요한지 알아보고 이를 사용할지 결정하는 것이 좋습니다.
뷰 전환 활성화 (SPA 모드)
섹션 제목: “뷰 전환 활성화 (SPA 모드)”공통 <head> 또는 공유 레이아웃 컴포넌트에 <ClientRouter /> 컴포넌트를 가져와서 추가합니다. Astro는 이전 페이지와 새 페이지 간의 유사성을 기반으로 기본 페이지 애니메이션을 생성하고 지원되지 않는 브라우저를 위한 대체 동작도 제공합니다.
아래 예시는 <CommonHead /> Astro 컴포넌트에 이 컴포넌트를 가져와 추가하여 Astro의 기본 페이지 탐색 애니메이션을 사이트 전체에 추가하는 방법을 보여줍니다. 여기에는 지원되지 않는 브라우저를 위한 기본 대체 제어 옵션도 포함됩니다.
---import { ClientRouter } from "astro:transitions";---<link rel="icon" type="image/svg+xml" href="/favicon.svg" /><meta name="generator" content={Astro.generator} />
<!-- 기본 메타 태그 --><title>{title}</title><meta name="title" content={title} /><meta name="description" content={description} />
<ClientRouter />Astro의 기본 클라이언트 측 탐색을 활성화하는 데 다른 구성은 필요하지 않습니다!
더 세밀한 제어를 위해 개별 요소에서 전환 지시어를 사용하거나 기본 클라이언트 측 탐색을 재정의하세요.
전환 지시어
섹션 제목: “전환 지시어”Astro는 공유되는 고유한 view-transition-name을 이전 페이지와 새 페이지 모두에서 발견된 해당 요소에 자동으로 할당합니다. 이 일치하는 요소 쌍은 요소의 타입과 DOM에서의 위치에 의해 추론됩니다.
탐색 중 페이지 전환 동작을 더 세밀하게 제어하려면 .astro 컴포넌트의 페이지 요소에 선택적 transition:* 지시어를 사용하세요.
transition:name: 이전/새 콘텐츠 애니메이션이 일치하는 Astro의 기본 요소를 재정의합니다. 전환 이름을 지정하여 DOM 요소 쌍을 연결할 수 있습니다.transition:animate: 애니메이션 타입을 지정하여 이전 요소를 새 요소로 대체하는 Astro의 기본 애니메이션을 재정의합니다. Astro의 내장 애니메이션 지시어를 사용하거나 사용자 정의 전환 애니메이션을 생성하세요.transition:persist: 이전 요소를 새 요소로 대체하는 Astro의 기본값을 재정의합니다. 대신 다른 페이지를 탐색할 때 컴포넌트와 HTML 요소를 유지합니다.
전환 이름 지정
섹션 제목: “전환 이름 지정”경우에 따라 해당 뷰 전환 요소를 직접 식별해야 할 수도 있습니다. transition:name 지시어를 사용하여 요소 쌍의 이름을 지정할 수 있습니다.
<aside transition:name="hero"><aside transition:name="hero">제공된 transition:name 값은 각 페이지에서 한 번만 사용할 수 있습니다. Astro가 적절한 이름을 유추할 수 없거나 일치하는 요소를 보다 세밀하게 제어하려는 경우 수동으로 직접 설정하세요.
상태 유지
섹션 제목: “상태 유지”
추가된 버전:
astro@2.10.0
transition:persist 지시어를 사용하여 페이지 탐색 간에 컴포넌트 및 HTML 요소를 교체하는 대신 유지할 수 있습니다.
예를 들어, 다음 <video>는 동일한 비디오 요소를 포함하는 다른 페이지로 이동할 때도 계속 재생됩니다. 이는 정방향 및 역방향 탐색 모두에서 작동합니다.
<video controls muted autoplay transition:persist> <source src="https://ia804502.us.archive.org/33/items/GoldenGa1939_3/GoldenGa1939_3_512kb.mp4" type="video/mp4" /></video>client: 지시어를 사용하는 UI 프레임워크 컴포넌트인 Astro 아일랜드에 지시어를 배치할 수도 있습니다. 해당 컴포넌트가 다음 페이지에 존재하는 경우 새 페이지의 아일랜드로 교체하는 대신 현재 상태를 가진 이전 페이지의 아일랜드가 계속 표시됩니다.
아래 예시에서 transition:persist 속성을 가진 <Counter /> 컴포넌트를 포함하는 페이지를 앞뒤로 탐색할 때 컴포넌트의 내부 카운트 상태는 재설정되지 않습니다.
<Counter client:load transition:persist initialCount={5} />이러한 방식으로 모든 상태를 유지할 수는 없습니다. transition:persist를 사용하더라도 뷰 전환 중에 CSS 애니메이션을 다시 시작하거나 iframe을 다시 불러오는 것은 피할 수 없습니다.
아일랜드 또는 요소가 두 페이지 간의 다른 컴포넌트에 있는 경우 해당 요소를 수동으로 직접 식별할 수도 있습니다.
<video controls muted autoplay transition:name="media-player" transition:persist/><MyVideo controls muted autoplay transition:name="media-player" transition:persist/>편리하게 transition:persist의 값으로 전환 이름을 사용할 수도 있습니다.
<video controls muted autoplay transition:persist="media-player">transition:persist-props
섹션 제목: “transition:persist-props”
추가된 버전:
astro@4.5.0
탐색 시 아일랜드의 props를 유지할지 여부를 제어합니다.
기본적으로 아일랜드에 transition:persist를 추가하면 탐색 시 상태가 유지되지만 컴포넌트는 새 props를 사용하여 다시 렌더링됩니다. 예를 들어, 이는 컴포넌트가 현재 페이지의 title과 같은 페이지별 props를 수신할 때 유용합니다.
transition:persist 외에 transition:persist-props를 설정하여 이 동작을 재정의할 수 있습니다. 이 지시어를 추가하면 기존 상태를 유지하는 것 외에도 아일랜드의 기존 props를 유지합니다. (새 값을 사용하는 렌더링이 다시 발생하지 않습니다.)
내장 애니메이션 지시어
섹션 제목: “내장 애니메이션 지시어”Astro는 기본 fade 전환을 재정의하는 몇 가지 내장 애니메이션을 제공합니다. transition:animate 지시어를 개별 요소에 추가하여 특정 전환의 동작을 사용자 정의합니다.
fade(기본값): 사전 정의된 크로스페이드 애니메이션입니다. 이전 콘텐츠는 페이드 아웃되고 새 콘텐츠는 페이드 인됩니다.initial: Astro의 사전 정의된 크로스페이드 애니메이션을 선택 해제하고 브라우저의 기본 스타일을 사용합니다.slide: 이전 콘텐츠가 왼쪽으로 슬라이드 아웃되고 새 콘텐츠가 오른쪽에서 슬라이드 인되는 애니메이션입니다. 역방향 탐색 시 애니메이션은 반대로 동작합니다.none: 브라우저의 기본 애니메이션을 비활성화합니다. 페이지의 모든 요소에 대한 기본 페이드를 비활성화하기 위해 페이지의<html>요소에 사용합니다.
지시어를 결합하여 페이지 애니메이션을 완벽하게 제어합니다. <html> 요소에 페이지 기본값을 설정하고 원하는 개별 요소를 재정의합니다.
아래 예시는 페이지의 나머지 부분에 대한 브라우저의 기본 페이드 애니메이션을 비활성화하면서 본문 콘텐츠에 대한 슬라이드 애니메이션을 생성합니다.
---import CommonHead from "../components/CommonHead.astro";---
<html transition:name="root" transition:animate="none"> <head> <CommonHead /> </head> <body> <header> ... </header> <!-- 단일 요소의 페이지 기본값을 재정의합니다. --> <main transition:animate="slide"> ... </main> </body></html>애니메이션 사용자 정의
섹션 제목: “애니메이션 사용자 정의”CSS 애니메이션 속성을 사용하여 전환의 모든 측면을 사용자 정의할 수 있습니다.
내장 애니메이션을 사용자 정의하려면 astro:transitions에서 애니메이션을 가져온 다음 사용자 정의 옵션을 전달합니다.
아래 예시는 내장된 fade 애니메이션의 지속 시간을 사용자 정의합니다.
---import { fade } from "astro:transitions";---<header transition:animate={fade({ duration: "0.4s" })}>다음 타입에 따라 정방향 및 역방향 동작과 새 페이지 및 이전 페이지를 모두 정의하여 transition:animate에 사용할 나만의 애니메이션을 정의할 수도 있습니다.
export interface TransitionAnimation { name: string; // 키프레임의 이름입니다. delay?: number | string; duration?: number | string; easing?: string; fillMode?: string; direction?: string;}
export interface TransitionAnimationPair { old: TransitionAnimation | TransitionAnimation[]; new: TransitionAnimation | TransitionAnimation[];}
export interface TransitionDirectionalAnimations { forwards: TransitionAnimationPair; backwards: TransitionAnimationPair;}다음 예시는 루트 레이아웃 파일의 <style is:global> 태그에서 사용자 정의 bump 애니메이션을 정의하는 데 필요한 모든 속성을 보여줍니다.
---import { ClientRouter } from "astro:transitions";---<html lang="ko"> <head> <ClientRouter /> </head> <body> <slot /> </body></html>
<style is:global> @keyframes bump { 0% { opacity: 0; transform: scale(1) translateX(200px); } 50% { opacity: 0.5; transform: scale(1.1); } 100% { opacity: 1; transform: scale(1) translateX(0); } }</style>애니메이션의 동작은 애니메이션을 사용하는 모든 컴포넌트의 프런트매터에 정의되어야 합니다.
---const anim = { old: { name: "bump", duration: "0.5s", easing: "ease-in", direction: "reverse", }, new: { name: "bump", duration: "0.5s", easing: "ease-in-out", },};
const customTransition = { forwards: anim, backwards: anim,};---<header transition:animate={customTransition}> ... </header>사용자 정의 애니메이션을 정의할 때 매우 유연하게 작업할 수 있습니다. 원하는 결과를 얻기 위해 정방향 및 역방향에 다른 객체를 사용하거나 이전 및 새 페이지에 대해 별도의 키프레임 애니메이션을 제공하는 등 특이한 조합을 고려할 수 있습니다.
라우터 제어
섹션 제목: “라우터 제어”<ClientRouter /> 라우터는 다음을 수신하여 탐색을 처리합니다.
<a>요소 클릭- 뒤로 및 앞으로 탐색 이벤트
다음 옵션을 사용하면 라우터에서 탐색이 발생하는 시점을 추가로 제어할 수 있습니다.
data-astro-reload: 전체 페이지 탐색을 강제하는<a>태그 속성data-astro-history="auto | push | replace": 브라우저 기록을 제어하는<a>태그 속성navigate(href, options): 탐색을 트리거하기 위해 모든 클라이언트 스크립트 또는 클라이언트 컴포넌트에서 사용할 수 있는 메서드
클라이언트 측 탐색 방지
섹션 제목: “클라이언트 측 탐색 방지”전체 페이지를 다시 로드하는 것을 방지하기 위해 관련된 두 페이지가 모두 <ClientRouter /> 라우터를 사용해야 하므로 클라이언트 측 라우팅을 통한 탐색이 불가능한 경우가 있습니다. 또한 모든 탐색 변경에서 클라이언트 측 라우팅을 원하지 않고 선택한 라우트에서 기존 페이지 탐색을 선호할 수도 있습니다.
data-astro-reload 속성을 <a> 또는 <form> 태그에 추가하여 링크별로 클라이언트 측 라우팅을 선택 해제할 수 있습니다. 이 속성은 기존 <ClientRouter /> 컴포넌트를 재정의하고 대신 탐색 중에 브라우저 새로 고침을 트리거합니다.
다음 예시는 홈페이지에서 아티클로 이동할 때만 클라이언트 측 라우팅을 방지하는 방법을 보여줍니다. 이렇게 하면 아티클 목록 페이지에서 동일한 페이지로 이동할 때는 히어로 이미지와 같은 공유 요소에 애니메이션을 적용할 수 있습니다.
<a href="/articles/emperor-penguins" data-astro-reload><a href="/articles/emperor-penguins">data-astro-reload 속성이 있는 링크는 라우터에서 무시되고 전체 페이지 탐색이 발생합니다.
탐색 트리거
섹션 제목: “탐색 트리거”navigate()를 사용하여 일반적으로 <ClientRouter /> 라우터에서 수신하지 않는 이벤트를 통해 클라이언트 측 탐색을 트리거할 수도 있습니다. astro:transitions/client 모듈의 이 함수는 스크립트와 클라이언트 지시어로 하이드레이션된 프레임워크 컴포넌트에서 사용할 수 있습니다.
다음 예시는 방문자를 메뉴에서 선택한 다른 페이지로 이동시키는 Astro 컴포넌트를 보여줍니다.
<script> import { navigate } from "astro:transitions/client";
// 선택한 옵션으로 이동합니다. document.querySelector("select").onchange = (event) => { let href = event.target.value; navigate(href); };</script><select> <option value="/play">시작</option> <option value="/blog">블로그</option> <option value="/about">소개</option> <option value="/contact">연락처</option></select>---import Form from "../components/Form.astro";import { ClientRouter } from "astro:transitions";---<html> <head> <ClientRouter /> </head> <body> <Form /> </body></html>다음 예시는 React의 <Form /> 컴포넌트에서 navigate()를 사용하여 동일한 기능을 구현합니다.
import { navigate } from "astro:transitions/client";
export default function Form() { return ( <select onChange={(e) => navigate(e.target.value)}> <option value="/play">시작</option> <option value="/blog">블로그</option> <option value="/about">소개</option> <option value="/contact">연락처</option> </select> );}그러면 <Form /> 컴포넌트는 클라이언트 지시어와 함께 <ClientRouter /> 라우터를 사용하는 Astro 페이지에서 렌더링될 수 있습니다.
---import Form from "../components/Form.jsx";import { ClientRouter } from "astro:transitions";---<html> <head> <ClientRouter /> </head> <body> <Form client:load /> </body></html>navigate 메서드는 다음 인수를 사용합니다.
href(필수) - 탐색할 새 페이지입니다.options- 다음 속성을 가진 선택적 객체입니다.history:"push"|"replace"|"auto""push": 라우터는history.pushState를 사용하여 브라우저 기록에 새 항목을 만듭니다."replace": 라우터는history.replaceState를 사용하여 탐색에 새 항목을 추가하지 않고 URL을 업데이트합니다."auto"(기본값): 라우터는history.pushState를 시도하지만, URL이 전환할 수 없는 URL인 경우 브라우저 기록을 변경하지 않고 현재 URL을 유지합니다.
formData:POST요청을 위한FormData객체입니다.
브라우저 기록을 통한 역방향 및 정방향 탐색을 위해 navigate()를 브라우저의 내장 함수인 history.back(), history.forward() 및 history.go()와 결합할 수 있습니다. 컴포넌트의 서버 측 렌더링 중에 navigate()가 호출되면 아무런 효과가 없습니다.
브라우저 기록의 항목 바꾸기
섹션 제목: “브라우저 기록의 항목 바꾸기”일반적으로 탐색할 때마다 새 항목이 브라우저 기록에 추가됩니다. 이를 통해 브라우저의 뒤로 및 앞으로 버튼을 사용하여 페이지 간 탐색이 가능합니다.
<ClientRouter /> 라우터를 사용하면 개별 <a> 태그에 data-astro-history 속성을 추가하여 기록 항목을 재정의할 수 있습니다.
data-astro-history 속성은 navigate() 함수의 history 옵션과 동일한 세 가지 값으로 설정할 수 있습니다.
data-astro-history: "push" | "replace" | "auto"
"push": 라우터는history.pushState를 사용하여 브라우저 기록에 새 항목을 만듭니다."replace": 라우터는history.replaceState를 사용하여 탐색에 새 항목을 추가하지 않고 URL을 업데이트합니다."auto"(기본값): 라우터는history.pushState를 시도하지만, URL이 전환할 수 없는 URL인 경우 브라우저 기록을 변경하지 않고 현재 URL을 유지합니다.
다음 예제는 /main 페이지로 이동하지만 탐색 기록에 새 항목을 추가하지 않습니다. 대신 기록의 현재 항목 (/confirmation)을 재사용하고 이를 덮어씁니다.
<a href="/main" data-astro-history="replace">이렇게 하면 /main 페이지에서 뒤로 이동할 때 브라우저에 /confirmation 페이지가 표시되지 않고 그 이전 페이지가 표시되는 효과가 있습니다.
양식을 사용하여 전환
섹션 제목: “양식을 사용하여 전환”
추가된 버전:
astro@4.0.0
<ClientRouter /> 라우터는 <form> 요소에서 페이지 내 전환을 트리거하며 GET 및 POST 요청을 모두 지원합니다.
기본적으로 Astro는 method가 POST로 설정된 경우 양식 데이터를 multipart/form-data로 제출합니다. 웹 브라우저의 기본 동작과 일치시키려면 enctype 속성을 사용하여 application/x-www-form-urlencoded로 인코딩된 데이터를 제출하세요.
<form action="/contact" method="POST" enctype="application/x-www-form-urlencoded">data-astro-reload 속성을 사용하여 개별 양식의 라우터 전환을 선택 해제할 수 있습니다.
<form action="/contact" data-astro-reload>사용자 입력을 통해 탐색하기
섹션 제목: “사용자 입력을 통해 탐색하기”navigate() API는 전달된 URL에 대한 검증을 수행하지 않습니다. 사용자 입력을 통해 탐색할 URL을 결정하는 경우, navigate()에 전달하기 전에 입력을 검증해야 합니다.
예를 들어 ?redirect 쿼리 매개변수를 검증하지 않고 사용하는 경우, 외부 사이트로 이동하거나 (예: ?redirect=http://example.com) 임의의 코드(예: ?redirect=javascript:alert('Evil code'))를 실행하는 데 사용될 수 있습니다.
이를 안전하게 구현하는 한 가지 방법은 알려진 경로 집합으로만 리디렉션되도록 하는 것입니다.
<script> import { navigate } from 'astro:transitions/client';
const params = new URLSearchParams(window.location.search); const redirect = params.get('redirect'); const allowedPaths = ['/home', '/about', '/contact'];
if (allowedPaths.includes(redirect)) { navigate(redirect); }</script>사이트 및 허용할 내용에 따라 필요한 검증의 방식이 달라집니다.
navigate() API와 함께 사용하는 경우, Astro의 실험적 콘텐츠 보안 정책을 활성화하여 교차 사이트 스크립팅 (XSS) 위험으로부터 보호하는 것을 고려해 보세요.
대체 옵션
섹션 제목: “대체 옵션”<ClientRouter /> 라우터는 뷰 전환을 지원하는 브라우저 (예: Chromium 브라우저)에서 가장 잘 작동하지만 다른 브라우저에 대한 기본 대체 지원도 포함합니다. 브라우저가 뷰 전환 API를 지원하지 않더라도 Astro의 클라이언트 라우터는 대체 옵션 중 하나를 사용하여 브라우저 내 탐색을 제공할 수 있습니다.
브라우저 지원에 따라, 모든 브라우저에서 유사한 경험을 제공하기 위한 애니메이션 효과를 적용할 요소에 name 또는 animate 전환 지시어를 명시적으로 설정해야 할 수 있습니다.
---import Layout from "../layouts/LayoutUsingClientRouter.astro";---<title transition:animate="fade">내 사이트에 대하여</title><ClientRouter /> 컴포넌트에 fallback 속성을 추가하고 이를 swap 또는 none으로 설정하여 Astro의 기본 대체 지원을 재정의할 수 있습니다.
animate(기본값, 권장): Astro는 페이지 콘텐츠를 업데이트하기 전에 사용자 정의 속성을 사용하여 뷰 전환을 시뮬레이션합니다.swap: Astro는 페이지에 애니메이션 효과를 적용하지 않습니다. 대신 이전 페이지가 새 페이지로 즉시 교체됩니다.none: Astro는 애니메이션 페이지 전환을 전혀 수행하지 않습니다. 대신 지원하지 않는 브라우저에서 전체 페이지 탐색을 수행합니다.
---import { ClientRouter } from "astro:transitions";---<title>나의 사이트</title>
<ClientRouter fallback="swap" />initial 브라우저 애니메이션은 Astro에서 시뮬레이션되지 않습니다. 따라서 현재 이 애니메이션을 사용하는 모든 요소의 애니메이션은 작동하지 않습니다.
클라이언트 측 탐색 프로세스
섹션 제목: “클라이언트 측 탐색 프로세스”<ClientRouter /> 라우터를 사용할 때, Astro의 클라이언트 측 탐색을 생성하기 위해 다음 단계가 발생합니다.
-
사이트 방문자가 다음 작업 중 하나를 통해 탐색을 트리거합니다.
- 사이트의 다른 페이지에 내부적으로 연결되는
<a>태그를 클릭합니다. - 뒤로 버튼을 클릭합니다.
- 앞으로 버튼을 클릭합니다.
- 사이트의 다른 페이지에 내부적으로 연결되는
-
라우터가 다음 페이지를 가져오기 시작합니다.
-
라우터는 HTML 요소에
data-astro-transition속성을 추가하고, 이 속성의 값을"forward"또는"back"으로 설정합니다. -
라우터는
document.startViewTransition을 호출합니다. 이는 브라우저 자체의 뷰 전환 프로세스를 트리거합니다. 중요한 것은 브라우저가 페이지의 현재 상태를 스크린샷한다는 것입니다. -
startViewTransition콜백 내부에서 라우터는 다음 이벤트 시퀀스로 구성된 교체 (swap)를 수행합니다.-
<head>의 콘텐츠가 교체되지만, 다음과 같은 일부 요소는 유지됩니다.- 스타일시트 DOM 노드가 새 페이지에 존재하는 경우, FOUC를 방지하기 위해 유지됩니다.
- 스크립트가 새 페이지에 존재하는 경우 유지됩니다.
transition:persist가 있는 다른 헤드 요소는 해당 요소가 새 페이지에도 존재하는 경우 유지됩니다.
-
<body>는 새 페이지의 요소로 완전히 교체됩니다. -
transition:persist로 표시된 요소는 해당 요소가 새 페이지에도 존재하는 경우 새 DOM으로 이동합니다. -
필요한 경우 스크롤 위치가 복원됩니다.
-
astro:after-swap이벤트가document에서 트리거됩니다. 이는 교체 (swap) 프로세스의 끝입니다.
-
-
라우터는 전환을 해결하기 전에 새 스타일시트가 로드될 때까지 기다립니다.
-
라우터는 페이지에 추가된 새 스크립트를 실행합니다.
-
astro:page-load이벤트가 발생합니다. 이는 탐색 프로세스의 끝입니다.
뷰 전환 시 스크립트 동작
섹션 제목: “뷰 전환 시 스크립트 동작”기존 Astro 프로젝트에 뷰 전환을 추가하면 일부 스크립트는 전체 페이지 새로 고침 때와 달리 페이지 탐색 후 다시 실행되지 않을 수 있습니다. 다음 정보를 사용하여 스크립트가 예상대로 실행되는지 확인하세요.
스크립트 순서
섹션 제목: “스크립트 순서”<ClientRouter /> 컴포넌트를 사용하여 페이지 간을 탐색할 때 스크립트는 브라우저 동작과 일치하도록 순차적으로 실행됩니다.
스크립트 재실행
섹션 제목: “스크립트 재실행”Astro의 기본 스크립트인 번들링된 모듈 스크립트는 한 번만 실행됩니다. 초기 실행 후에는 전환 후 새 페이지에 스크립트가 존재하더라도 무시됩니다.
번들링된 모듈 스크립트와 달리 인라인 스크립트는 여러 번 방문한 페이지에 존재하는 경우, 사용자가 사이트를 방문하는 동안 다시 실행될 가능성이 있습니다. 인라인 스크립트는 방문자가 스크립트 없는 페이지로 이동했다가 스크립트가 존재하는 페이지로 다시 돌아오면 다시 실행될 수도 있습니다.
뷰 전환을 사용하면 일부 스크립트는 전체 페이지 새로 고침 때와 달리 페이지 탐색 후 다시 실행되지 않을 수 있습니다. 클라이언트 측 라우팅 중 발생하는 여러 이벤트를 감지하고, 해당 이벤트가 발생할 때 특정 동작을 실행할 수 있습니다. 기존 스크립트를 이벤트 리스너로 래핑하여 탐색 주기에서 적절한 타이밍에 실행할 수 있습니다.
다음 예제는 페이지 탐색이 끝날 때 실행되는 astro:page-load에 대한 이벤트 리스너에 모바일 “햄버거” 메뉴에 대한 스크립트를 래핑하여 새 페이지로 이동한 후 메뉴를 클릭했을 때 반응하도록 만듭니다.
document.addEventListener("astro:page-load", () => { document.querySelector(".hamburger").addEventListener("click", () => { document.querySelector(".nav-links").classList.toggle("expanded"); });});다음 예제는 새 페이지가 이전 페이지를 대체한 직후, 그리고 DOM 요소가 화면에 그려지기 전에 발생하는 astro:after-swap 이벤트에 대한 응답으로 실행되는 함수를 보여줍니다. 새 페이지가 렌더링되기 전에 다크 모드 테마를 확인하고 필요한 경우 설정하여 페이지 이동 후 라이트 모드 테마가 깜박이는 것을 방지합니다.
<script is:inline> function applyTheme() { localStorage.theme === "dark" ? document.documentElement.classList.add("dark") : document.documentElement.classList.remove("dark"); }
document.addEventListener("astro:after-swap", applyTheme); applyTheme();</script>data-astro-rerun
섹션 제목: “data-astro-rerun”
추가된 버전:
astro@4.5.0
모든 전환 후에 인라인 스크립트가 다시 실행되도록 하려면 data-astro-rerun 속성을 추가하세요. 스크립트에 속성을 추가하면 암시적으로 is:inline도 추가되므로 Astro에서 번들링 및 처리되지 않은 스크립트에만 사용할 수 있습니다.
<script is:inline data-astro-rerun>...</script>클라이언트 측 탐색 중에 페이지가 로드될 때마다 스크립트가 실행되도록 하려면 수명 주기 이벤트에 의해 실행되어야 합니다. 예를 들어 DOMContentLoaded에 대한 이벤트 리스너는 astro:page-load 수명 주기 이벤트로 대체될 수 있습니다.
인라인 스크립트에 전역 상태를 설정하는 코드가 있는 경우, 이 상태는 스크립트가 두 번 이상 실행될 수 있다는 점을 고려해야 합니다. <script> 태그에서 전역 상태를 확인하고 가능한 경우 코드를 조건부로 실행합니다. window가 유지되기 때문에 이 방법이 작동합니다.
<script is:inline> if (!window.SomeGlobal) { window.SomeGlobal = {}; }</script>수명 주기 이벤트
섹션 제목: “수명 주기 이벤트”<ClientRouter /> 라우터는 탐색 중에 document에서 여러 이벤트를 발생시킵니다. 이러한 이벤트는 탐색 수명 주기에 대한 훅을 제공하여 새 페이지가 로드 중임을 나타내는 요소를 표시하거나, 기본 동작을 재정의하거나, 탐색이 완료될 때 상태를 복원하는 등의 작업을 수행할 수 있도록 합니다.
탐색 프로세스에는 새 콘텐츠가 로드되는 준비 단계, 이전 페이지의 콘텐츠가 새 페이지의 콘텐츠로 대체되는 DOM 교체 단계, 스크립트가 실행되고 로딩이 완료된 것으로 보고되며 정리 작업이 수행되는 완료 단계가 포함됩니다.
Astro의 뷰 전환 API 수명 주기 이벤트는 순서대로 다음과 같습니다.
before- 이벤트를 사용하면 발생하려는 작업에 영향을 주고 수정할 수 있으며, after- 이벤트는 단계가 완료되었음을 알리는 알림입니다.
일부 작업은 모든 이벤트 중에 트리거될 수 있지만, 최상의 결과를 위해 일부 작업은 특정 이벤트 중에만 수행할 수 있습니다. 예를 들어 준비 전에 로딩 스피너를 표시하거나 콘텐츠 교체 전에 애니메이션 쌍을 재정의하는 경우가 있습니다.
astro:before-preparation
섹션 제목: “astro:before-preparation”
추가된 버전:
astro@3.6.0
탐색이 시작된 후 (예: 사용자가 링크를 클릭한 후), 콘텐츠가 로드되기 전 준비 단계의 시작 부분에서 발생하는 이벤트입니다.
이 이벤트는 다음과 같은 용도로 사용됩니다.
- 로딩이 시작되기 전에 로딩 스피너를 표시하는 등의 작업을 수행합니다.
- 외부 URL이 아닌 템플릿에 정의된 콘텐츠를 로드하는 등 로딩을 변경합니다.
- 사용자 정의 애니메이션을 위해 탐색
direction(일반적으로forward또는backward)을 변경합니다.
다음은 콘텐츠가 로드되기 전에 스피너를 로드하고 로드 직후 중지하기 위해 astro:before-preparation 이벤트를 사용하는 예시입니다. 이러한 방식으로 loader 콜백을 사용하면 코드의 비동기 실행이 가능합니다.
<script is:inline> document.addEventListener("astro:before-preparation", (event) => { const originalLoader = event.loader; event.loader = async function () { const { startSpinner } = await import("./spinner.js"); const stop = startSpinner(); await originalLoader(); stop(); }; });</script>astro:after-preparation
섹션 제목: “astro:after-preparation”
추가된 버전:
astro@3.6.0
새 페이지의 콘텐츠가 로드되어 문서로 구문 분석된 후 준비 단계의 끝에서 발생하는 이벤트입니다. 이 이벤트는 뷰 전환 단계 전에 발생합니다.
이 예제에서는 astro:before-preparation 이벤트를 사용하여 로딩 표시기를 보여주기 시작하고 astro:after-preparation 이벤트를 사용하여 중지합니다.
<script is:inline> document.addEventListener("astro:before-preparation", () => { document.querySelector("#loading").classList.add("show"); }); document.addEventListener("astro:after-preparation", () => { document.querySelector("#loading").classList.remove("show"); });</script>이것은 위 예제보다 스피너를 불러오는 더 간단한 버전입니다. 리스너의 모든 코드를 동기적으로 실행할 수 있다면 loader 콜백에 연결할 필요가 없습니다.
astro:before-swap
섹션 제목: “astro:before-swap”
추가된 버전:
astro@3.6.0
준비 단계에서 채워진 새 문서가 현재 문서를 대체하기 전에 발생하는 이벤트입니다. 이 이벤트는 뷰 전환 내부에서 발생하며, 사용자는 여전히 이전 페이지의 스냅샷을 보고 있습니다.
이 이벤트는 교체 전에 변경 사항을 생성하는 데 사용할 수 있습니다. 이벤트의 newDocument 속성은 들어오는 문서를 나타냅니다. 다음은 localStorage의 브라우저 라이트 또는 다크 모드 기본 설정을 새 페이지로 전달하는 예시입니다.
<script> document.addEventListener("astro:before-swap", (event) => { event.newDocument.documentElement.dataset.theme = localStorage.getItem("darkMode") ? "dark" : "light"; });</script>astro:before-swap 이벤트는 교체의 구현을 변경하는 데에도 사용할 수 있습니다. 기본 교체 구현은 헤드 콘텐츠를 변경하고, 이전 문서에서 유지되는 요소를 newDocument로 이동한 다음, 전체 body를 새 문서의 요소로 바꿉니다.
수명 주기의 이 시점에서, 기존 문서의 전체 콘텐츠를 변경하는 등 (일부 다른 라우터가 수행하는 작업) 나만의 교체 구현을 정의하도록 선택할 수 있습니다.
<script is:inline> document.addEventListener("astro:before-swap", (event) => { event.swap = () => { diff(document, event.newDocument); }; });</script>사용자 정의 교체 함수 구현
섹션 제목: “사용자 정의 교체 함수 구현”
추가된 버전:
astro@4.15.0
astro:transitions/client 모듈의 swapFunctions 객체는 문서 속성, 페이지 요소 및 스크립트 실행 처리를 포함하여 특정 교체 관련 작업을 처리하는 5가지 유틸리티 함수를 제공합니다. 이러한 함수는 사용자 정의 교체 구현을 정의하는 데 직접 사용할 수 있습니다.
다음 예제는 이러한 함수를 사용하여 Astro의 내장 교체 구현을 재현하는 방법을 보여줍니다.
<script> import { swapFunctions } from "astro:transitions/client";
// `window.document`를 `doc`으로 대체합니다. function mySwap(doc: Document) { swapFunctions.deselectScripts(doc); swapFunctions.swapRootAttributes(doc); swapFunctions.swapHeadElements(doc); const restoreFocusFunction = swapFunctions.saveFocus(); swapFunctions.swapBodyElement(doc.body, document.body); restoreFocusFunction(); }
document.addEventListener("astro:before-swap", (event) => { event.swap = () => mySwap(event.newDocument); });<script>사용자 정의 교체 구현은 이 템플릿으로 시작하고, 필요에 따라 개별 단계를 사용자 정의 논리로 추가하거나 대체할 수 있습니다.
astro:after-swap
섹션 제목: “astro:after-swap”새 페이지가 이전 페이지를 대체한 직후 발생하는 이벤트입니다. document에서 이 이벤트를 수신하고 새 페이지의 DOM 요소가 렌더링되고 스크립트가 실행되기 전에 발생하는 작업을 트리거할 수 있습니다.
나가는 페이지에서 수신될 때, 이 이벤트는 새 페이지로 전달해야 하는 DOM의 상태를 전달하고 복원하는 데 유용합니다.
예를 들어, 이는 다크 모드 클래스 이름 (<html class="dark-mode">)을 추가할 수 있는 안전한 수명 주기의 최신 시점이지만, 이전 이벤트에서 그렇게 하는 것이 좋습니다.
astro:after-swap 이벤트는 브라우저 기록이 업데이트되고 스크롤 위치가 설정된 직후에 발생합니다.
따라서 이 이벤트를 대상으로 하는 한 가지 용도는 기록 탐색에 대한 기본 스크롤 복원을 재정의하는 것입니다. 다음 예제는 각 탐색에 대해 가로 및 세로 스크롤 위치를 페이지의 왼쪽 상단 모서리로 재설정합니다.
document.addEventListener("astro:after-swap", () => window.scrollTo({ left: 0, top: 0, behavior: "instant" }),);astro:page-load
섹션 제목: “astro:page-load”새 페이지가 사용자에게 표시되고 차단 스타일 및 스크립트가 로드된 후 페이지 탐색이 끝날 때 발생하는 이벤트입니다. document에서 이 이벤트를 수신할 수 있습니다.
<ClientRouter /> 컴포넌트는 사전 렌더링된 페이지의 초기 페이지 탐색과 이후의 모든 탐색 (앞으로 또는 뒤로)에서 이 이벤트를 발생시킵니다.
이 이벤트를 사용하면 모든 페이지 탐색에서 코드를 실행할 수 있습니다. 예를 들어 탐색 중에 손실될 수 있는 이벤트 리스너를 설정할 수 있습니다.
<script> document.addEventListener("astro:page-load", () => { // 첫 페이지 로딩 시와 모든 탐색 후에 실행됩니다. setupStuff(); // 예: 이벤트 리스너 추가 });</script>접근성
섹션 제목: “접근성”클라이언트 측 라우팅을 활성화하고 페이지 전환에 애니메이션을 적용하는 것은 모두 접근성 문제를 동반하며, Astro는 뷰 전환을 사용하는 사이트를 가능한 한 기본적으로 접근 가능하게 만드는 것을 목표로 합니다.
라우트 알림
섹션 제목: “라우트 알림”
추가된 버전:
astro@3.2.0
<ClientRouter /> 컴포넌트는 클라이언트 측 라우팅 중 페이지 탐색을 위한 경로 알림 기능을 포함합니다. 이를 활성화하기 위한 구성이나 작업은 필요하지 않습니다.
보조 기술은 탐색 후 새 페이지 제목을 알림으로써 방문자에게 페이지가 변경되었음을 알립니다. 기존 전체 페이지 브라우저 새로 고침을 사용하는 서버 측 라우팅을 사용하는 경우 새 페이지가 로드된 후 기본적으로 이 작업이 수행됩니다. 클라이언트 측 라우팅에서는 <ClientRouter /> 컴포넌트가 이 작업을 수행합니다.
클라이언트 측 라우팅에 라우트 알림을 추가하기 위해 컴포넌트는 aria-live 속성이 assertive로 설정된 요소를 새 페이지에 추가합니다. 이는 AT (보조 기술)에 즉시 알리도록 지시합니다. 컴포넌트는 알림 텍스트를 결정하기 위해 우선 순위 순으로 다음을 확인합니다.
<title>(존재하는 경우)- 첫 번째
<h1> - 페이지의
pathname
접근성을 위해 각 페이지에 항상 <title>을 포함하는 것을 강력히 권장합니다.
prefers-reduced-motion
섹션 제목: “prefers-reduced-motion”Astro의 <ClientRouter /> 컴포넌트는 prefer-reduced-motion 설정이 감지될 때마다 대체 애니메이션을 포함하여 모든 뷰 전환 애니메이션을 비활성화하는 CSS 미디어 쿼리를 포함합니다. 대신 브라우저는 애니메이션 없이 DOM 요소를 간단히 교체합니다.