Upgrade to Pro — share decks privately, control downloads, hide ads and more …

選ばれたのは Next.jsでした - Next.jsによるServer Side OGP ⽣成 / Next.js was chosen - Server Side OGP generation with Next.js

選ばれたのは Next.jsでした - Next.jsによるServer Side OGP ⽣成 / Next.js was chosen - Server Side OGP generation with Next.js

isoken26 (LINE株式会社)
UIT meetup vol.11『フロントエンド紅白LT合戦』での発表資料です
https://uit.connpass.com/event/197740/

LINE Developers

December 18, 2020
Tweet

More Decks by LINE Developers

Other Decks in Technology

Transcript

  1. ۀ຿ ࣾ಺޻਺؅ཧγεςϜ  ϑϩϯτΤϯυ։ൃ  +4ϓϩδΣΫτͷ54Խ  &&ςετ؀ڥͷߏங 会社:LINE Growth

    Technology 株式会社 所属:開発室 / UITチーム(GT) -*/&%&7&-01&3%":  ϑϩϯτΤϯυ։ൃ 役職:フロントエンドエンジニア 名前:Isomura Kenjiro 好きな技術:TypeScript, React @isoken26
  2. 0(1ͷಈతੜ੒ͱ͸ 0(1ͷಈతੜ੒ • OGPの画像とかをページ毎に切り替える https://example.com/items/1 https:// example.com/items/2 https ://example.com https://example.com

    EXAMPLE SHOP EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE SHOP EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE EXAMPLE
  3. https://expamle.com/item/3 https://expamle.com/item/2 https://expamle.com/item/1 0(1ͷදࣔͷ࢓૊Έ͓͞Β͍ • サーバ側へリクエストが⾏った時にOGP⽤の<meta>タグを含む htmlが⽣成されている状態 0(1ͷಈతੜ੒ OGP対応しているアプリ ②URLクロール

    ③response https://expamle.com/item/3 https ://example.com EXAMPLE SHOP EXAMPLE EXAMPLE EXAMPLE EXAMPLE https://expamle.com/item/2 https ://example.com EXAMPLE SHOP EXAMPLE EXAMPLE EXAMPLE EXAMPLE https://expamle.com/item/1 https ://example.com EXAMPLE SHOP EXAMPLE EXAMPLE EXAMPLE EXAMPLE ①URLが⼊⼒される ④OGPカードの⽣成
  4. /FYUKTʹ͓͚Δ44( 443 ಈత0(1ͷੜ੒ • Next.jsではFile-System Routing • pagesディクトリ配下の構成(file名など)に基づいてroutingが構成 前提知識として •

    各ページのdefault exportされているReactコンポネントがページコンポネントとして renderingされる // pages/users/index.tsx const Users = () => { return ( <div>Users</div> ) } export default Users
  5. // pages/users/index.tsx export default function Users({ users }) { return

    ( <ul> {users.map((user) => ( <li>{user.name}</li> ))} </ul> ) } // SSG with Data export const getStaticProps = async () => { const res = await fetch('/users’) const users = await res.json() return { props: { users, }, } } σʔλ෇͖ͷ44( ಈత0(1ͷੜ੒ • getStaticPropsという⾮同期関数をexportすること でデータをpropsに紐づけてbuildすることも • getStaticPropsはサーバーサイドでのみ実⾏され • getStaticPropsはブラウザからアクセスできない • getStaticPropsはビルド時のみ実⾏される
  6. 443͢Δʹ͸ ಈత0(1ͷੜ੒ getStaticProps getServerSideProps リクエストごとに実⾏される ビルド時に実⾏される // pages/users/index.tsx export default

    function Users({ users }) { return ( <ul> {users.map((user) => ( <li>{user.name}</li> ))} </ul> ) } // export const getStaticProps = async () => { export const getServerSideProps = async () => { const res = await fetch('/users’) const users = await res.json() return { props: { users, }, } }
  7. 443Ͱ0(1Λಈతʹੜ੒͢Δ ಈత0(1ͷੜ੒ getServerSidePropsの実装 export async const getServerSideProps = (context) =>

    { // id === "0000" const { id } = context.query const res = await fetch(`/sessions/${id}`) const session = await res.json() return { props: { session }} } ①context.queryから[id]にあたるidを取得 ②idを元にセッションの詳細情報を取得 ②取得したセッション詳細情報をページコンポネントにpropsとして渡す
  8. 443Ͱ0(1Λಈతʹੜ੒͢Δ ಈత0(1ͷੜ੒ ページコンポネントSessionの実装 ①渡されたsession詳細データからogpImageUrlを`og:imageにセットする` ②渡されたsession詳細データからogpUrlを`og:url`にセットする ②データが紐付いたらDOMをrenderingする // pages/sessions/[id].tsx cosnt Session

    = ({ session }) => ( 〜 <meta property="og:title" content="..." /> <meta property="twitter:card" content="..." /> <meta property=“og:image” content={session.ogpImageUrl} /> <meta property="og:url" content={session.ogpUrl} /> 〜 ) ApplicationLayoutというラッパーコ ンポネントを省略している
  9. 443Ͱ0(1Λಈతʹੜ੒͢Δ ಈత0(1ͷੜ੒ // pages/sessions/[id].tsx cosnt Session = ({ session })

    => ( 〜 <meta property="og:title" content="..." /> <meta property="twitter:card" content="..." /> <meta property="og:image” content={session.ogpImageUrl} /> <meta property="og:url" content={session.ogpUrl} /> 〜 ) export async const getServerSideProps = (context) => { // id === "0000" const { id } = context.query const res = await fetch(`/sessions/${id}`) const session = await res.json() return { props: { session }} } export default Session; 全体