diff --git a/examples/40_view_transitions/package.json b/examples/40_view_transitions/package.json
new file mode 100644
index 000000000..e5dbec250
--- /dev/null
+++ b/examples/40_view_transitions/package.json
@@ -0,0 +1,22 @@
+{
+ "name": "40_view_transitions",
+ "version": "0.1.0",
+ "type": "module",
+ "private": true,
+ "scripts": {
+ "dev": "waku dev",
+ "build": "waku build",
+ "start": "waku start"
+ },
+ "dependencies": {
+ "react": "19.0.0",
+ "react-dom": "19.0.0",
+ "react-server-dom-webpack": "19.0.0",
+ "waku": "0.21.18"
+ },
+ "devDependencies": {
+ "@types/react": "19.0.8",
+ "@types/react-dom": "19.0.3",
+ "typescript": "5.7.3"
+ }
+}
diff --git a/examples/40_view_transitions/src/components/AboutPage.tsx b/examples/40_view_transitions/src/components/AboutPage.tsx
new file mode 100644
index 000000000..d611a23ce
--- /dev/null
+++ b/examples/40_view_transitions/src/components/AboutPage.tsx
@@ -0,0 +1,25 @@
+const AboutPage = () => (
+
+
+ About Us
+
+
+
This is the about page with a different background color.
+
+
+);
+
+export default AboutPage;
diff --git a/examples/40_view_transitions/src/components/HomePage.tsx b/examples/40_view_transitions/src/components/HomePage.tsx
new file mode 100644
index 000000000..e060354e5
--- /dev/null
+++ b/examples/40_view_transitions/src/components/HomePage.tsx
@@ -0,0 +1,25 @@
+const HomePage = () => (
+
+
+ Welcome Home
+
+
+
This is the home page. Navigate to see view transitions in action!
+
+
+);
+
+export default HomePage;
diff --git a/examples/40_view_transitions/src/components/RootLayout.tsx b/examples/40_view_transitions/src/components/RootLayout.tsx
new file mode 100644
index 000000000..bc87933b0
--- /dev/null
+++ b/examples/40_view_transitions/src/components/RootLayout.tsx
@@ -0,0 +1,21 @@
+import type { ReactNode } from 'react';
+import { Link } from 'waku/router/client';
+import '../styles.css';
+
+const RootLayout = ({ children }: { children: ReactNode }) => (
+
+);
+
+export default RootLayout;
diff --git a/examples/40_view_transitions/src/entries.tsx b/examples/40_view_transitions/src/entries.tsx
new file mode 100644
index 000000000..cf5fdabd2
--- /dev/null
+++ b/examples/40_view_transitions/src/entries.tsx
@@ -0,0 +1,34 @@
+import { createPages } from 'waku/router/server';
+import type { PathsForPages } from 'waku/router';
+
+import HomePage from './components/HomePage';
+import AboutPage from './components/AboutPage';
+import RootLayout from './components/RootLayout';
+
+const pages = createPages(async ({ createPage, createLayout }) => [
+ createLayout({
+ render: 'static',
+ path: '/',
+ component: RootLayout,
+ }),
+
+ createPage({
+ render: 'static',
+ path: '/',
+ component: HomePage,
+ }),
+
+ createPage({
+ render: 'static',
+ path: '/about',
+ component: AboutPage,
+ }),
+]);
+
+declare module 'waku/router' {
+ interface RouteConfig {
+ paths: PathsForPages;
+ }
+}
+
+export default pages;
diff --git a/examples/40_view_transitions/src/styles.css b/examples/40_view_transitions/src/styles.css
new file mode 100644
index 000000000..8908dcfbc
--- /dev/null
+++ b/examples/40_view_transitions/src/styles.css
@@ -0,0 +1,43 @@
+@keyframes fade-in {
+ from {
+ opacity: 0;
+ }
+}
+
+@keyframes fade-out {
+ to {
+ opacity: 0;
+ }
+}
+
+@keyframes slide-from-right {
+ from {
+ transform: translateX(30px);
+ }
+}
+
+@keyframes slide-to-left {
+ to {
+ transform: translateX(-30px);
+ }
+}
+
+::view-transition-old(page-title) {
+ animation:
+ fade-out 0.5s ease-in-out forwards,
+ slide-to-left 0.5s ease-in-out forwards;
+}
+
+::view-transition-new(page-title) {
+ animation:
+ fade-in 0.5s ease-in-out forwards,
+ slide-from-right 0.5s ease-in-out forwards;
+}
+
+::view-transition-old(page-content) {
+ animation: fade-out 0.5s ease-in-out forwards;
+}
+
+::view-transition-new(page-content) {
+ animation: fade-in 0.5s ease-in-out forwards;
+}
diff --git a/examples/40_view_transitions/tsconfig.json b/examples/40_view_transitions/tsconfig.json
new file mode 100644
index 000000000..84d0d542f
--- /dev/null
+++ b/examples/40_view_transitions/tsconfig.json
@@ -0,0 +1,15 @@
+{
+ "compilerOptions": {
+ "strict": true,
+ "target": "esnext",
+ "downlevelIteration": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "moduleResolution": "bundler",
+ "skipLibCheck": true,
+ "noUncheckedIndexedAccess": true,
+ "exactOptionalPropertyTypes": true,
+ "types": ["react/experimental"],
+ "jsx": "react-jsx"
+ }
+}
diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml
index d85d93870..5ed3ae79d 100644
--- a/pnpm-lock.yaml
+++ b/pnpm-lock.yaml
@@ -1063,6 +1063,31 @@ importers:
specifier: 5.7.3
version: 5.7.3
+ examples/40_view_transitions:
+ dependencies:
+ react:
+ specifier: 19.0.0
+ version: 19.0.0
+ react-dom:
+ specifier: 19.0.0
+ version: 19.0.0(react@19.0.0)
+ react-server-dom-webpack:
+ specifier: 19.0.0
+ version: 19.0.0(react-dom@19.0.0(react@19.0.0))(react@19.0.0)(webpack@5.97.1)
+ waku:
+ specifier: 0.21.18
+ version: link:../../packages/waku
+ devDependencies:
+ '@types/react':
+ specifier: 19.0.8
+ version: 19.0.8
+ '@types/react-dom':
+ specifier: 19.0.3
+ version: 19.0.3(@types/react@19.0.8)
+ typescript:
+ specifier: 5.7.3
+ version: 5.7.3
+
examples/41_path-alias:
dependencies:
react: