【Next.js + Supabase】SSR(Server Components)でデータ取得と出力するには?【App Router】
Next.js 13から導入された「Server Components」という概念によって、Supabaseの利用環境も大きく変わったことと思います。
Server Componentsでデータ取得してSSRするにはどうすればいいか分からないという方もいると思うので記事化することにしました。
※不要な要素を削ぎ落とした最低限な書き方にしています。実際に使うときは自分なりに使いやすい方法を考えてみましょう!
【はじめに】@supabase/ssr を使用しよう!
色々と面倒なことは Supabase 公式パッケージの「@supabase/ssr」がオススメです。
npm install '@supabase/ssr
でインストールしておきましょう!
それでは、下記から書き方を説明します!
Server Components を作ってみよう
データ取得と出力を行うコンポーネントを作成します。
import { cookies } from "next/headers";
import { createServerClient } from "'@supabase/ssr";
export const PostsView = async () => {
const cookieStore = cookies();
const supabase =
createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
cookies: {
get(name: string) {
return cookieStore.get(name)?.value;
},
}
});
const { data:posts } = await supabase.from('posts') .select(`*`);
return (
<>
{posts.map((thePost) => (
<div key={thePost.uuid}>
<p className="title">{thePost.title}</p>
<p className="text">{thePost.contents}</p>
</div>
))}
</>
);
}
Supabaseの posts
テーブルからデータを取得し、
結果を元に各要素を出力してくれるコンポーネントです。
次に、このコンポーネント自体を出力するための記述をする必要があります。
Suspense でデータ取得状況に応じて表示を切り替えよう
先程作った PostsView
コンポーネントはデータ取得を伴うため、必ずしもすぐに表示されるとは限りません。データ取得が完了しない間は「読み込み中」などのテキストを表示させたいと思います。
import { Suspense } from "react";
import { PostsView } from "@/components/posts";
export default function HomePage () {
return (
<>
<Suspense fallback={<p>データ読み込み中...</p>}>
<PostsView />
</Suspense>
</>
)
}
これで先程の PostsView
を出力できます。
ポイントは Suspense
です。 Suspense はReactが提供する機能で、処理が終わるまで fallback
に指定したコンポーネントを出力してくれて、処理完了後は <PostsView />
を出力してくれます。
データ取得に応じて useState 等で状態管理を行う必要が無い便利な機能です!
Suspenseで囲ったコンポーネントはSSRされるのでSEO的にも優れています。
また、next/link
でページ遷移した時にデータ取得がすぐに完了しないときは fallback
のコンポーネントを出力してくれるのでユーザーに状況が伝わりやすくてUX的にも優れています。
データ取得に失敗したときの表示はどうすればいいの?
データ取得は100%成功するとは限りません。エラー時にはどうすればいいのかも掲載しておきます。
ErrorBoundary
という仕組みが用意されていますが、現状は https://www.npmjs.com/package/react-error-boundary のようなパッケージを使って実装しておくと良いかと思います。
Discussion