Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
App Routerの紹介
Search
Yohei Iino
February 23, 2024
Technology
170
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
App Routerの紹介
Yohei Iino
February 23, 2024
More Decks by Yohei Iino
See All by Yohei Iino
1年半放置したExpo製アプリを最新化してみた
wheatandcat
0
120
作成中のFlutterアプリの中間発表
wheatandcat
0
98
最近読んだ技術書を簡単紹介
wheatandcat
0
120
ユニバーサルリンク/アプリリンクを使ってQRコードでゲストログインできるようにする
wheatandcat
0
400
Firebase App Checkを実装したので紹介
wheatandcat
0
370
PlanetScaleの無料プランがなくなるので、NeonとTiDBを試してみた
wheatandcat
0
440
Flutter HooksとRiverpodの解説
wheatandcat
0
610
T3 Stack(応用編: Next Auth & SSRの実装紹介)
wheatandcat
1
420
Flutter × GraphQLでアプリを作ってみる
wheatandcat
0
360
Other Decks in Technology
See All in Technology
M5Stackで作る BLEマウス GPSログの世界
tomokusaba
0
190
組み立てて楽しむ AWS Blocks 入門
kmiya84377
0
230
しろおびから始める!ログ活用の第一歩
shumei_ito
0
920
Claude Code本は、どのように執筆チームで書かれたか
oikon48
1
360
事業活動を AI Ready にする攻めと守りのデータエンジニアリング / data-engineering-for-ai-ready-business
pei0804
7
2.7k
自分で立ててみるLLMサービス
y_sera15
0
160
全PRの83%が AIレビューだけでマージできるようになった開発組織は その後どうなったか @2026/10
athug
0
140
【Data Engineering Summit2026_登壇資料】医療ビッグデータ×AIエージェントを支えるデータ基盤とハーネスエンジニアリング
jmdc_presentation
0
140
自主式軟體工廠
philipz
0
260
会社説明資料
persolserverworks
0
9.7k
AI 時代の Azure エンジニアリング ~ 私たちは何を磨き、何を任せるのか ~
chack411
1
610
Getting Started with Google Antigravity
glaforge
0
230
Featured
See All Featured
Amusing Abliteration
ianozsvald
1
340
Technical Leadership for Architectural Decision Making
baasie
3
600
A Soul's Torment
seathinner
8
3.7k
Side Projects
sachag
456
43k
Reality Check: Gamification 10 Years Later
codingconduct
0
2.3k
We Are The Robots
honzajavorek
0
400
CoffeeScript is Beautiful & I Never Want to Write Plain JavaScript Again
sstephenson
162
16k
Six Lessons from altMBA
skipperchong
29
4.5k
svc-hook: hooking system calls on ARM64 by binary rewriting
retrage
2
620
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
520
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
4
4.4k
Agile Leadership in an Agile Organization
kimpetersen
PRO
0
280
Transcript
App Routerの紹介 Press Space for next page
自己紹介 📝 飯野陽平(wheatandcat) 🏢 法人設立(合同会社UNICORN 代表社員) 💻 Work: シェアフル株式会社CTO 📚
Blog: https://www.wheatandcat.me/ 🛠 今までに作ったもの memoir ペペロミア MarkyLinky
App Routerとは? Next.js 13.4で追加された新しいルーティング機構 従来のNext.jsのルーティングはPage Router RSC(React Server Components)の使用を前提と設計
RSC(React Server Components) とは? Reactでサーバーサイドでレンダリングできるコンポーネントを宣言できる仕組み 元々、Reactにはクライアントサイドでレンダリングするクライアントコンポーネントしかなかった SSRは、クライアントコンポーネントをサーバーサイドでレンダリングする仕組み RSCを使用することでサーバーサイド固有の機能を実装できる 例えばReact内で直接データベースにアクセスすることなどが可能 逆にRSCではクライアントサイド固有の機能は使用できない
例えば、useStateやuseEffectなどのHooksは使用できない 宣言した時点でエラーになる RSCで宣言されたコンポーネントはブラウザ側で読み込みbundleされたJavaScriptには含まれないため、読 み込むファイルサイズは小さくなる
App Routerのルーティング基本機構 従来のPage Routerのルーティング機構 App Routerのルーティング機構 src └─ pages ├─
index.tsx → / └─ items ├─ [id].tsx → /items/[id] └─ [id] └─ share.tsx → /items/[id]/share src └─ app ├─ page.tsx → / └─ items └─ [id] ├─ page.tsx → /items/[id] └─ share └─ page.tsx → /items/[id]/share
ルーティング毎に動的にfavicon、OG画像を変更する App Routerのルーティング機構だと以下のように設定が可能 以下、書き方の参考 src/app/icon.tsx src └─ app ├─ layout.tsx
→ 共通設定 └─ items └─ [id] ├─ icon.tsx → 動的favicon を変更 └─ opengraph-image.tsx → 動的OG 画像を変更
データアクセス & レンダリングの構造① App RouterはデフォルトはRSCでレンダリングされる、以下、コードの例 export default function Home() {
return ( <div className="container"> <h1 className="text-5xl"> Sample App </h1> <CrudShowcase /> </div> ); } async function CrudShowcase() { const session = await getServerAuthSession(); if (session?.user) { const url = await api.url.existsByUserId.query({userId: String(session?.user.id)}); if (url) redirect(`/schedule/${String(url?.id)}`); } return <CreateUrl />; }
データアクセス & レンダリングの構造① App RouterはデフォルトはRSCでレンダリングされる、以下、コードの例 async function CrudShowcase() { export
default function Home() { return ( <div className="container"> <h1 className="text-5xl"> Sample App </h1> <CrudShowcase /> </div> ); } const session = await getServerAuthSession(); if (session?.user) { const url = await api.url.existsByUserId.query({userId: String(session?.user.id)}); if (url) redirect(`/schedule/${String(url?.id)}`); } return <CreateUrl />; }
データアクセス & レンダリングの構造① App RouterはデフォルトはRSCでレンダリングされる、以下、コードの例 const session = await getServerAuthSession();
if (session?.user) { const url = await api.url.existsByUserId.query({userId: String(session?.user.id)}); if (url) redirect(`/schedule/${String(url?.id)}`); } export default function Home() { return ( <div className="container"> <h1 className="text-5xl"> Sample App </h1> <CrudShowcase /> </div> ); } async function CrudShowcase() { return <CreateUrl />; }
データアクセス & レンダリングの構造① App RouterはデフォルトはRSCでレンダリングされる、以下、コードの例 return <CreateUrl />; export default
function Home() { return ( <div className="container"> <h1 className="text-5xl"> Sample App </h1> <CrudShowcase /> </div> ); } async function CrudShowcase() { const session = await getServerAuthSession(); if (session?.user) { const url = await api.url.existsByUserId.query({userId: String(session?.user.id)}); if (url) redirect(`/schedule/${String(url?.id)}`); } }
データアクセス & レンダリングの構造② "use client"; export function CreateUrl() { const
router = useRouter(); const createMutation = api.url.create.useMutation({ onSuccess: (data) => { router.push(`/items/${data.id}`); }, }); const onCreate = useCallback(() => { createMutation.mutate(); }, [createMutation]); return ( <button className="button" onClick={onCreate} > 新しいデータを作る </button> ); }
データアクセス & レンダリングの構造② "use client"; export function CreateUrl() { const
router = useRouter(); const createMutation = api.url.create.useMutation({ onSuccess: (data) => { router.push(`/items/${data.id}`); }, }); const onCreate = useCallback(() => { createMutation.mutate(); }, [createMutation]); return ( <button className="button" onClick={onCreate} > 新しいデータを作る </button> ); }
データアクセス & レンダリングの構造② export function CreateUrl() { const router =
useRouter(); const createMutation = api.url.create.useMutation({ onSuccess: (data) => { router.push(`/items/${data.id}`); }, }); const onCreate = useCallback(() => { createMutation.mutate(); }, [createMutation]); return ( <button className="button" onClick={onCreate} > 新しいデータを作る </button> ); } "use client";
データアクセス & レンダリングの構造③ RSCではasync/awaitが使用できる RSCではhooksは使用できないのでデータ更新で使用するuseMutationはクライアントコンポーネントで実 装する必要がある RSCでデータ取得する場合は、直接データベースにアクセスが可能なので以下のように実装が可能 export default async
function Page({ params }: { params: { id: string } }) { const session = await getServerAuthSession(); const url = await api.url.exists.query({ id: params.id }); if (url === null) { // 存在しないURL の場合はトップページに戻す redirect("/"); } ... 省略
データアクセス & レンダリングの構造③ RSCではasync/awaitが使用できる RSCではhooksは使用できないのでデータ更新で使用するuseMutationはクライアントコンポーネントで実 装する必要がある RSCでデータ取得する場合は、直接データベースにアクセスが可能なので以下のように実装が可能 export default async
function Page({ params }: { params: { id: string } }) { const session = await getServerAuthSession(); const url = await api.url.exists.query({ id: params.id }); if (url === null) { // 存在しないURL の場合はトップページに戻す redirect("/"); } ... 省略
データアクセス & レンダリングの構造③ RSCではasync/awaitが使用できる RSCではhooksは使用できないのでデータ更新で使用するuseMutationはクライアントコンポーネントで実 装する必要がある RSCでデータ取得する場合は、直接データベースにアクセスが可能なので以下のように実装が可能 const url =
await api.url.exists.query({ id: params.id }); if (url === null) { // 存在しないURL の場合はトップページに戻す redirect("/"); } export default async function Page({ params }: { params: { id: string } }) { const session = await getServerAuthSession(); ... 省略
実装してみる PR: App Routerに変更する 以下、デモしながら説明 App Routerの移行で以下の処理はシンプルに実装できた例1 旧コード 新コード App
Routerの移行で以下の処理はシンプルに実装できた例2 旧コード 新コード
まとめ App RouterはRSCを前提としたルーティング機構になっている RSCを使用するとデータ取得周りはシンプルに実装できる ただ、App Routerはフロントエンド界隈では賛否両論で、当面Web文脈では議論されていきそう 一休レストランで Next.js App Router
から Remix に乗り換えた話 元々Next.jsはWeb標準のAPIに準拠していないことが問題視されていて、App Routerでより、その点が 強まった 逆にRemixはWeb標準のAPIに準拠した思想で実装されているので対象的になっている
ご清聴ありがとうございました 🎉