ç¬ãèšåœ¢åŒã§ç¶ŽããOGP & SSRã
OGPç»åã衚瀺ãããã
ããããWebãµãŒãã¹ãäœã£ããã
ãããã°ã©ãã³ã°ã«é¢ããèšäºãæçš¿ã§ããWebãµãŒãã¹ã ã
ããã®ãµã€ãã®èšäºãTwitterãšãã§ã·ã§ã¢ããŠããã£ãŠã人æ°ãåºããšãããªã
ãã·ã§ã¢ããŠããã£ããšãã«ããã£ã±ãOGPç»åã衚瀺ãããæ¹ãããããªã
ããããããããªãèšäºã®ã¿ã€ãã«ãšããµã€ãåãå
¥ã£ããµã ãç»åã¿ãããªã®ã衚瀺ããããªã
ãããããã®ããã«ã¯ãHTMLã®metaã¿ã°ã«ãOGPã®æ
å ±ãå
¥ãããã«ããªããšãªã
Next.jsã§headã¿ã°ã®äžãããã
ãä»åã®WebãµãŒãã¹ã§ã¯ãããã³ãéšåãNext.js[1]ã§å®è£
ããããã
ãNext.jsã§headã¿ã°ã®äžãããã£ãŠãmetaã¿ã°ã«OGPæ
å ±ãåã蟌ããã
<Head>
<meta property="og:title" content="èšäºã¿ã€ãã«" />
<meta property="og:description" content="èšäºã®èª¬æ" />
<meta property="og:image" content="OGPç»åã®URL" />
<meta name="twitter:card" content="summary_large_image" />
</Head>
ããããmetaã¿ã°ã¯ãããªæãã ãªã
ãèšäºã¿ã€ãã«ãOGPç»åã®URLã¯ãAPIããååŸããæååãå
¥ããããã«ããŠãããã
ãåèšäºããšã«ãåçã«å€ããããããªã
ãSWRã§APIããååŸããããŒã¿ã¯ãapiDataãšããååã®å€æ°ã«å
¥ã£ãŠããããã»ã»ã»ã
<Head>
<meta property="og:title" content={apiData.title} />
<meta property="og:description" content={apiData.description} />
<meta property="og:image" content={apiData.thumbnailUrl} />
<meta name="twitter:card" content="summary_large_image" />
</Head>
ãâãããªæãã ãªã
ããããããããããµã€ãããããã€ãçŽããŠã»ã»ã»ã
ã詊ãã«Twitterã§èšäºãã·ã§ã¢ããŠã¿ããã
衚瀺ãããªã
ããããOGPã®ããã®metaã¿ã°ãæžããã¯ããªã®ã«ãOGPç»åã衚瀺ãããªããã
ããããã§åå ã調ã¹ãŠã¿ããã»ã»ã»ã
Twitterã®ã¯ããŒã©ãŒã¯ãSPAãè§£éã§ããªãããã
ããµããµããã©ãããã
ãSWRã䜿ã£ãŠAPIããååŸããèšäºã®æ
å ±ããmetaã¿ã°ã«å
¥ããã»ã»ã»ã
ãããã§ã¯ãã¡ã¿ããã ã
TwitterãããURLãå«ãã ãã€ãŒããããããã
Twitterããããããã®ãµã€ããèŠã«è¡ã£ãŠãOGPç»åããã£ããããã€ãŒãäžã«è¡šç€ºãããã
Twitterããããã®ãµã€ãã ãªã
TwitterãããŒãã»ã»ã»ãªãã ãããé£ããJavaScriptãããŠããã£ãŠããã£ããïŒã
TwitterããããšãOGPæ å ±ã¯ã»ã»ã»ç¡ãïŒã
â»ã€ã¡ãŒãžã§ã
ãâãããªæãã«ãªã£ãŠããŸãã¿ããã ã
ãTwitterã®ã¯ããŒã©ãŒã¯ãJavaScriptãå®ç§ã«è§£éã§ããèš³ã§ã¯ãªãããã
ãSPAçãªã¯ã©ã€ã¢ã³ããµã€ãã®ææ³ã§metaã¿ã°ãåã蟌ãã§ããããŸã衚瀺ãããªããããã
SSRïŒServer-Side RenderingïŒãããªããšãããªã
ãã¯ããŒã©ãŒãHTMLãèªã¿èŸŒãã§ãããJavaScriptã§metaã¿ã°ããããã®ã§ã¯ãã¡ã£ãŠããšã ãªã
ãã¯ããŒã©ãŒãHTMLãèªã¿èŸŒãã æç¹ã§ãmetaã¿ã°ã«æ
å ±ãå
¥ã£ãŠããªããšãã¡ã£ãŠããšãã
ãã€ãŸãmetaã¿ã°ã¯ããµãŒããµã€ãã§æžã蟌ãã§ããå¿
èŠããããã ãªã
ãã ããããµãŒããµã€ãã»ã¬ã³ããªã³ã°ãšãããã ãªã
Next.jsã®å ŽåãgetServerSidePropsã䜿ã
ãã©ããããèšäºããŒãžã®jsxãã¡ã€ã«å
ã«ã
ãgetServerSidePropsãšãã颿°ãæžããŠãexportããã°ããã¿ããã ã
export async function getServerSideProps({ query }) {
// APIããããŒã¿ãååŸ
const res = await fetch(`https://.../api/ogp/articles/${query.id}`)
const ogpData = await res.json()
// ãããpropsã«å
¥ããŠããªããžã§ã¯ããšããŠè¿ã
return { props: { ogpData } }
}
ããããããã ãªã
ãmetaã¿ã°ã®æ¹ã¯...ã
<Head>
<meta property="og:title" content={ogpData.title} />
<meta property="og:description" content={ogpData.description} />
<meta property="og:image" content={ogpData.thumbnailUrl} />
<meta name="twitter:card" content="summary_large_image" />
</Head>
ãâããã ãªã
ããããããäžåºŠãããã€ãçŽããŠã
ã詊ãã«èšäºãã·ã§ã¢ããŠã¿ããã
衚瀺ããã
ããããOGPç»åã衚瀺ããããã
ãç®çéæã ïŒã
â»ç¢ºèªã§ããªãå Žåã¯ãTwitterã«ãŒãã®ãã£ãã·ã¥ãã¯ãªã¢ããŠã¿ãŸãããã
â»ãšããããTwitterã®Card Validatoräžã§ç¢ºèªããã°ããã¿ããã§ãã
ãŸãšã
- Twitterã®ã¯ããŒã©ãŒã¯ãSPAãè§£éã§ããªã
- ã¯ã©ã€ã¢ã³ããµã€ãã§
metaã¿ã°ãæžããŠããã¡
- ã¯ã©ã€ã¢ã³ããµã€ãã§
- ã¯ããŒã©ãŒãHTMLãååŸããæç¹ã§ãmetaã¿ã°ã«OGPæ
å ±ãæžããŠãªããšãã¡
- åèšäºããšã«åçã«OGPæ å ±ãåã蟌ã¿ããå Žåã«ã¯ããµãŒãåŽã§ã®åŠçãå¿ èŠ
- Next.jsã§ã¯
getServerSidePropsã䜿çšããŠå®è£ ãã
泚æç¹
- ãµãŒãåŽã§ã®åŠçãå¿
èŠãªããããã¹ãã£ã³ã°ãµãŒãã¹ã®éžå®æã«æ³šæãå¿
èŠ
- ãã¹ãã£ã³ã°å ãVercelãAWS Amplify Consoleã«ããŠãããšããããã
- Serverless Next.js Componentã䜿çšããŠãå¯èœ
- ã©ã¡ããå éšçã«ã¯AWSã®Lambda@Edgeã䜿çšããŠããããã
ä»ã®ããæ¹
- SGïŒéççæïŒ
- ãããã€åã«htmlãã¡ã€ã«ãéççæããã¿ã€ãã³ã°ã§ãAPIãšéä¿¡ããŠ
metaã¿ã°ãæžããŠãããã°ãSSRããå¿ èŠã¯ãããŸãããèŠä»¶ã«ããããã§ããã
- ãããã€åã«htmlãã¡ã€ã«ãéççæããã¿ã€ãã³ã°ã§ãAPIãšéä¿¡ããŠ
-
React補ã®ãã¬ãŒã ã¯ãŒã¯ã§ãã â©ïž
ããã¿ã¯ã誰ãã®å¿ãåããäœéšããã¯ãããžãŒãšãã¶ã€ã³ã§åœ¢ã«ãããšã³ãžãã¢ãªã³ã°ïŒã¯ãªãšã€ãã£ããã©ã³ãã§ããæ¬ãµã€ãã§ã¯ãããã¿ã¡ã³ããŒããããžã§ã¯ãçã§åŸãç¥èŠ/çµéšã玹ä»ããŠããŸããçŸå Žã§ã®ç¥èŠ/çµéšãã§ããã ãå€ããæ©ã瀟äŒã«éå ããããšãç®çã«ããŠãããããææ³ãç°è«ãªã©ããã°ãã²ãã£ãŒãããã¯ãé¡ãããŸãã
Discussion