CONTENT
ここから
13. トップページを作る
app/page.tsx を編集します。
// app/page.tsx
import { BlogSearch } from '@/components/BlogSearch';
import { CategoryBadge } from '@/components/CategoryBadge';
import { getSortedPosts } from '@/data/posts';
import Link from 'next/link';
/**
* 役割: トップページを表示する
* 入力: なし
* 出力: ヒーロー、注目記事、記事一覧を含むトップページ
*/
export default function HomePage() {
const posts = getSortedPosts();
const featuredPost = posts[0];
return (
<main>
<section className="mx-auto grid max-w-6xl gap-10 px-5 py-16 md:grid-cols-[1.1fr_0.9fr] md:items-center">
<div>
<p className="text-sm font-black uppercase tracking-[0.28em] text-slate-400">
Gifu Local Entertainment
</p>
<h1 className="mt-4 text-4xl font-black leading-tight tracking-tight text-slate-950 md:text-6xl">
岐阜の小さな熱狂を、
<br />
記事で残す。
</h1>
<p className="mt-6 max-w-2xl text-base leading-8 text-slate-600 md:text-lg">
岐阜市、大垣、高山、関市などで起きたローカルエンタメニュースを紹介するブログアプリです。
まずは静的データで作り、あとからCMSやDBに拡張できる形にしています。
</p>
<div className="mt-8 flex flex-wrap gap-3">
<a
href="#posts"
className="rounded-full bg-slate-950 px-6 py-3 text-sm font-bold text-white transition hover:bg-slate-700"
>
記事を見る
</a>
<Link
href={`/posts/${featuredPost.slug}`}
className="rounded-full border border-slate-300 bg-white px-6 py-3 text-sm font-bold text-slate-950 transition hover:border-slate-950"
>
注目記事を読む
</Link>
</div>
</div>
<article className="rounded-[2rem] border border-slate-200 bg-white p-7 shadow-xl shadow-slate-200/70">
<div className="mb-5 flex flex-wrap items-center gap-3">
<CategoryBadge category={featuredPost.category} />
<span className="text-xs font-bold text-slate-400">
Featured
</span>
</div>
<h2 className="text-2xl font-black leading-snug tracking-tight text-slate-950">
{featuredPost.title}
</h2>
<p className="mt-4 text-sm leading-7 text-slate-600">
{featuredPost.description}
</p>
<div className="mt-6 flex flex-wrap gap-2">
{featuredPost.tags.map((tag) => (
<span
key={tag}
className="rounded-full bg-slate-100 px-3 py-1 text-xs font-semibold text-slate-500"
>
#{tag}
</span>
))}
</div>
<Link
href={`/posts/${featuredPost.slug}`}
className="mt-8 inline-flex text-sm font-black text-slate-950"
>
続きを読む →
</Link>
</article>
</section>
<BlogSearch initialPosts={posts} />
</main>
);
}
ここでやっていること
トップページでは、まず記事を取得しています。
const posts = getSortedPosts();
一番新しい記事を注目記事にしています。
const featuredPost = posts[0];
その下に検索付きの記事一覧を表示しています。
<BlogSearch initialPosts={posts} />
この流れが理解できると、かなりNext.jsらしいページ設計が見えてきます。