Files
blog-nextjs/app/page.tsx
gbanyan 7d85446ac5 feat: add page transition animations and loading indicators
- Add nextjs-toploader for instant top progress bar on navigation
- Add next-view-transitions for View Transitions API page transitions
- Enhance template.tsx page enter animation (0.45s, scale effect)
- Replace next/link with next-view-transitions Link for smooth transitions
- Add prefers-reduced-motion support for accessibility

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-02-13 23:07:51 +08:00

70 lines
2.1 KiB
TypeScript

import { Link } from 'next-view-transitions';
import { getAllPostsSorted } from '@/lib/posts';
import { siteConfig } from '@/lib/config';
import { PostListItem } from '@/components/post-list-item';
import { TimelineWrapper } from '@/components/timeline-wrapper';
import { SidebarLayout } from '@/components/sidebar-layout';
import { JsonLd } from '@/components/json-ld';
import { HeroSection } from '@/components/hero-section';
export default function HomePage() {
const posts = getAllPostsSorted().slice(0, siteConfig.postsPerPage);
// CollectionPage Schema for homepage
const collectionPageSchema = {
'@context': 'https://schema.org',
'@type': 'CollectionPage',
name: `${siteConfig.name} 的最新動態`,
description: siteConfig.description,
url: siteConfig.url,
inLanguage: siteConfig.defaultLocale,
isPartOf: {
'@type': 'WebSite',
name: siteConfig.title,
url: siteConfig.url,
},
about: {
'@type': 'Blog',
name: siteConfig.title,
description: siteConfig.description,
},
};
return (
<>
<JsonLd data={collectionPageSchema} />
<section className="space-y-6">
<SidebarLayout>
<h1 className="sr-only">
{siteConfig.name} {siteConfig.tagline}
</h1>
<HeroSection
title={`${siteConfig.name} 的最新動態`}
tagline={siteConfig.tagline}
/>
<div>
<div className="mb-3 flex items-baseline justify-between">
<h2 className="type-small font-semibold uppercase tracking-[0.4em] text-slate-500 dark:text-slate-400">
</h2>
<Link
href="/blog"
prefetch={true}
className="text-xs text-blue-600 hover:underline dark:text-blue-400"
>
</Link>
</div>
<TimelineWrapper>
{posts.map((post, index) => (
<PostListItem key={post._id} post={post} priority={index === 0} />
))}
</TimelineWrapper>
</div>
</SidebarLayout>
</section>
</>
);
}