ããŒãžããšã«éççæãšãµãŒããŒåŽã¬ã³ããªã³ã°ã®äž¡æ¹ãå®è¡ããã¡ãœãããæäŸããããšã«ãããNext.jsãå®å šã«ãã€ããªããã«ãªãããšãèš±å¯ããŸãã
getStaticProps
- next build
æç¹ã§éççæïŒSSGïŒã«ãªããã€ã³ããŸããgetServerSideProps
-ãªã³ããã³ãã§ã¬ã³ããªã³ã°ãããµãŒããŒåŽã¬ã³ããªã³ã°ïŒSSRïŒã«ãªããã€ã³ããŸããgetStaticPaths
-éççæïŒSSGïŒãå®è¡ããããã®åçã«ãŒãã®ãã©ã¡ãŒã¿ãŒã®ãªã¹ããè¿ããŸããã®RFCã¯ãAPIã®è¿œå ã«ã€ããŠã®ã¿èª¬æããŠããŸãã ãã¹ãŠã®æ°æ©èœã¯å®å šãªäžäœäºææ§ãããã段éçã«æ¡çšã§ããŸãã ãã®RFCã¯éæšå¥šãå°å ¥ããŠããŸããã
Webãµã€ããŸãã¯Webã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ããå ŽåãéåžžãéççæïŒSSGïŒãŸãã¯ãµãŒããŒåŽã¬ã³ããªã³ã°ïŒSSRïŒã®2ã€ã®æŠç¥ããéžæããå¿ èŠããããŸãã
Next.jsã§ã¯ã代ããã«ã䜿çšããæŠç¥ãããŒãžããšã«éžæã§ãããã€ããªããã¢ããªã±ãŒã·ã§ã³ãæ§ç¯ã§ããŸãã Next.js 9以éã getInitialProps
ãªãããŒãžã¯éçã«æé©åããã next build
.html
ãã¡ã€ã«ãšããŠåºåãããŸãã
ãã ããç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã®éçããŒãžãçæããªããããŒã¿ãã§ãããå®è¡ããããšããå§ãããŸãã
ããšãã°ãCMSãŸãã¯ãµã€ãã®ããã°ã»ã¯ã·ã§ã³ããããŒã±ãã£ã³ã°ããŒãžãéçã«çæããŸãã
ãã®å Žåã getInitialProps
ã䜿çšãããšãSSRã«ãªããã€ã³ããŸãã
Next.jsã«ã¯çŸåšnext export
ã³ãã³ãããããããã«ããã¢ããªã±ãŒã·ã§ã³ã¯å®å
šã«SSGã«ãªããNext.jsã®ãã€ããªãããªæ§è³ªã倱ãããŸãã
next export
ãgetInitialProps
ãšäžç·ã«äœ¿çšãããšãå¥ã®åé¡ãçºçããŸãã getInitialProps
ã¯ãã«ãæã«åŒã³åºãããŸããïŒããã¯ãã°ãããããšã§ãïŒã next/link
ã䜿çšããŠããŒãžéã移åãããšã next export
ã䜿çšãã代ããã«getInitialProps
ãã¯ã©ã€ã¢ã³ãåŽãšåŒã°ããŸãã next export
çµæã
ããã¯ãããŒã¿ãœãŒã¹ïŒCMS / APIãšã³ããã€ã³ãïŒãã¯ã©ã€ã¢ã³ãåŽã®é·ç§»ã§çŽæ¥åŒã³åºãããããšãæå³ããŸããããŒã¿ãœãŒã¹ãããŠã³ããŠããå ŽåãããŒãžéã移åãããšãã«ã¯ã©ã€ã¢ã³ãåŽã®é·ç§»ãäžæããŸãã
SSGã®ãããŒãŠãŒã¶ãŒãšHashiCorpã®ãããªNext.jsã®next export
ïŒ@ jescalanã«æè¬ïŒãšååãã2ã€ã®æ°ããããŒã¿ãã§ããæ¹æ³ãå°å
¥ããããã®é©åãªå¶çŽãåºç¯å²ã«èª¿æ»ããŸããïŒ getStaticProps
ãšgetServerSideProps
ã ãã ããåçã«ãŒãã®éçããŒãžãéçã«çæãããã©ã¡ãŒã¿ãŒãæäŸããæ¹æ³ããããŸãã getStaticPaths
ïŒããŒãžããšã®exportPathMap
眮ãæãïŒã
ãããã®æ°ããæ¹æ³ã«ã¯ãSSGãšSSRã«ãªããã®ãæ確ã«åºå¥ãããããã getInitialProps
ã¢ãã«ã«æ¯ã¹ãŠå€ãã®å©ç¹ããããŸãã
getStaticProps
ã¯ããã«ãæã«éçã«çæãããããŒãžãããŒã¯ããŸãïŒ next build
å®è¡ããŠããå ŽåïŒgetStaticPaths
䜿çšãããšãåçã«ãŒãã®ãã«ãæã«çæãããã©ã¡ãŒã¿ãŒã®ãªã¹ããè¿ãããšãã§ããŸããgetServerSideProps
ã¯ããã¹ãŠã®ãªã¯ãšã¹ãã§ãµãŒããŒåŽã§ã¬ã³ããªã³ã°ãããããŒãžãããŒã¯ãããµãŒããŒã䜿çšãããšãã®çŸåšã®getInitialProps
åäœã«æã䌌ãŠããŸãããããã®ã¡ãœãããåé¢ããããšã§ãTypeScriptã䜿çšããŠå
¥åã§ããæ£ããã³ã³ããã¹ããªããžã§ã¯ããæäŸããããšãã§ããŸãã ç¹å®ã®ã¬ã³ããªã³ã°æŠç¥ãéžæãããšãæ£ããå€ãåŸãããŸããçŸåšgetInitialProps
ã§ã¯ãTypeScriptã䜿çšãããšãã«SSGãšSSRã§äœãå©çšã§ããããæšæž¬ããå¿
èŠããããŸãã
ããã«ããããã®ã¡ãœãããæ瀺çã«ããããšã§ãããŸããŸãªãã¬ãŒããªããããæ確ã«ææžåã§ããããã«ãªããŸãã
ãããã®ã¡ãœããã¯ãã¹ãŠãããŒãžã³ã³ããŒãã³ããã¡ã€ã«ã®æäžäœã§ããã getInitialProps
ããã«ããã¹ãããããšã¯ã§ããªãããšã«æ³šæããŠãã ããã
getStaticProps
getStaticProps
ãããšãããŒãžã¯ãã«ãæã«éçã«ã¬ã³ããªã³ã°ãããŸãïŒSSGïŒã
ãã®æ°ããã¡ãœããã䜿çšãããšã next build
æç¹ã§.html
ãã¡ã€ã«ã«éçã«çæãããããŒãžã®ããŒã¿ãã§ãããå®è¡ã§ããŸãã
Next.jsã¯ã next build
æç¹ã§getStaticProps
ã®çµæãä¿æããJSONãã¡ã€ã«ãèªåçã«çæããŸãã ããã¯ãã¯ã©ã€ã¢ã³ãåŽã®ã«ãŒãã£ã³ã°ã«äœ¿çšãããŠããŸãã
ã¯ã©ã€ã¢ã³ãåŽãnext/link
ãŸãã¯next/router
ãä»ããŠã«ãŒãã£ã³ã°ããå ŽåãNext.jsã¯ãã®JSONãã¡ã€ã«ããã§ããããŠãããŒãžãã¯ã©ã€ã¢ã³ãåŽã«ã¬ã³ããªã³ã°ããããã«å¿
èŠãªå°éå
·ãååŸããŸãã
ããããã£ã¯props
ããŒã§è¿ããããããå°æ¥çã«ä»ã®ãªãã·ã§ã³ãå°å
¥ã§ããŸãã
// pages/index.js
// getStaticProps is only called server-side
// In theory you could do direct database queries
export async function getStaticProps(context) {
return {
// Unlike `getInitialProps` the props are returned under a props key
// The reasoning behind this is that there's potentially more options
// that will be introduced in the future.
// For example to allow you to further control behavior per-page.
props: {}
};
}
context
ã«ã¯æ¬¡ã®ãã®ãå«ãŸããŸãã
params
-åçã«ãŒãäžã®ãã©ã¡ãŒã¿ãgetStaticPaths
ããã¯ãåçã«ãŒãã®getStaticProps
䜿çšéã®æ¡åŒµã§ãã
getStaticPaths
ã¯ã exportPathMap
ãæã€å¿
èŠæ§ã眮ãæããããŒãžããšã«æ©èœããŸãã
以äžã®slug
ã®äŸã®ããã«ãåçãã©ã¡ãŒã¿ãæã€URLã®ãªã¹ããéçã«çæãããå Žåãããããã§ãã Next.jsã¯ãURLã®ãªã¹ããè¿ãããšãã§ããgetStaticPaths
ã¡ãœãããæäŸããŸãã ããã¯async
ã¡ãœãããªã®ã§ãCMSãªã©ã®ããŒã¿ãœãŒã¹ãããã®ãªã¹ãããã§ããããããšãã§ããŸãã
// pages/blog/[slug].js
// `getStaticProps` gets a `params` object holding the dynamic parameters
// For `/blog/hello-world` it would look like `{ slug: 'hello-world }`
export async function getStaticProps({ params }) {
return {
props: {}
};
}
// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
return {
paths: [
// This renders /blog/hello-world to HTML at build time
{ params: { slug: "hello-world" } }
]
};
}
å€ãã®å Žåããã«ãæã«ã¢ããªã±ãŒã·ã§ã³å
ã®ãã¹ãŠã®å¯èœãªã«ãŒããäºåã«ã¬ã³ããªã³ã°ããããªãå ŽåããããŸãïŒããšãã°ãæ°çŸäžã®è£œåãããå ŽåïŒã ãã®ãããNext.jsã¯ãããŒãžããŸã çæãããŠããªãå Žåã«ãããŒã¿ãªãã®ããŒãžã®ã¬ã³ããªã³ã°ã§ããfallback
ããŒãžãèªåçã«çæããŸãïŒããŒãç¶æ
ã衚瀺ã§ããããã«ããŸãïŒã
ãµãŒãã³ã°ã®æ£ç¢ºãªåäœã¯æ¬¡ã®ãšããã§ãã
ãã«ãæã«çæãããªãã£ããã¹ã404ã«ãªãããã«ãããå Žåã¯ã getStaticPaths
ããfallback: false
ãè¿ãããšã§ãå¯èœã§ãã
// `getStaticPaths` allows the user to return a list of parameters to
// render to HTML at build time.
export async function getStaticPaths() {
return {
// Opt-out of the described fallback behavior
fallback: false,
paths: [
// This renders /blog/hello-world to HTML at build time
{ params: { slug: "hello-world" } }
]
};
}
getServerSideProps
getServerSideProps
ã䜿çšããå ŽåãããŒãžã¯éçã«çæãããïŒSSGïŒã代ããã«ãµãŒããŒãžã®ãã¹ãŠã®èŠæ±ã§ãªã³ããã³ãã§ã¬ã³ããªã³ã°ãããŸãïŒSSRïŒã
Next.jsã¯ã getServerSideProps
ãåŒã³åºããçµæãè¿ãAPIãšã³ããã€ã³ããèªåçã«å
¬éããŸãã ããã¯ãã¯ã©ã€ã¢ã³ãåŽã®ã«ãŒãã£ã³ã°ã«äœ¿çšãããŠããŸãã
ã¯ã©ã€ã¢ã³ãåŽãnext/link
ãŸãã¯next/router
ãä»ããŠã«ãŒãã£ã³ã°ããå ŽåãNext.jsã¯ãã®å
¬éãããAPIãšã³ããã€ã³ãããã§ããããŠãããŒãžãã¯ã©ã€ã¢ã³ãåŽã«ã¬ã³ããªã³ã°ããããã«å¿
èŠãªå°éå
·ã«å€æãããJSONããŒã¿ãååŸããŸãã
ãã®æ¹æ³ã¯çŸåšã®getInitialProps
ã«æã䌌ãŠããŸãããäž»ãªéãã¯getServerSideProps
ãåžžã«ãã©ãŠã¶ã§ã¯ãªããµãŒããŒåŽã§å®è¡ãããããšã§ãã ãµãŒããŒåŽã®ã¬ã³ããªã³ã°ãŸãã¯ã¯ã©ã€ã¢ã³ãåŽã®ã«ãŒãã£ã³ã°æã®APIãã§ããã®ããããã
getStaticProps
åæ§ã«ãããããã£ã¯props
ããŒã§è¿ãããŸãã
// pages/index.js
// getServerSideProps is only called server-side
// In theory you could do direct database queries
export async function getServerSideProps(context) {
return {
// Unlike `getInitialProps` the props are returned under a props key
// The reasoning behind this is that there's potentially more options
// that will be introduced in the future.
// For example to allow you to further control behavior per-page.
props: {}
};
}
context
ã«ã¯æ¬¡ã®ãã®ãå«ãŸããŸãã
params
-åçã«ãŒãã®ãã©ã¡ãŒã¿req
-HTTPãªã¯ãšã¹ããªããžã§ã¯ãres
-HTTPå¿çãªããžã§ã¯ãquery
-ã¯ãšãªæååïŒããã«ã€ããŠã¯å®å
šã«ã¯ããããŸããããããããå¿
èŠã§ãïŒ@ timneutkens ã @ Timer ã @ ijjk ã @ lfadesã«ãã£ãŠäœæãããŸããã @ rauchg ã @ jescalanãªã©ãšã®ã³ã©ãã¬ãŒã·ã§ã³ð
export async function getStaticProps(context) { return { // Unlike `getInitialProps` the props are returned under a props key // The reasoning behind this is that there's potentially more options // that will be introduced in the future. // For example to allow you to further control behavior per-page. props: {} }; }
props
å
ã«å«ããããšãã§ãããã®ä»¥å€ã®è¿œå ããŒã¿ãè¿ãå¿
èŠãããç¶æ³ã確èªããããšã«èå³ããããŸãã ãããŒãžããšã®åäœãããã«å¶åŸ¡ããããšããã€ã³ã©ã€ã³ã®èª¬æã¯å°ãææ§ã§ããã
ãšãŠãé¢çœããïŒ åœŒã¯getInitialProps
代ããã«ãªãã®ã§ããããããããšãäžç·ã«ãªããŸããïŒ ããšãã°ãç§ãã¡ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãããŒã¿ãã§ããAPIã¯å
Œ
±ãµãŒãã¹ã§ãã ãããã£ãŠãã¯ã©ã€ã¢ã³ãåŽã®ããã²ãŒã·ã§ã³ã§ã¯ãã¯ã©ã€ã¢ã³ããAPIã¬ã€ã€ãŒãçŽæ¥åŒã³åºãããšãæåŸ
ããŸãããSSRã§ã¯ãµãŒããŒããããåŒã³åºããŸãã ä»åŸããã®ãŠãŒã¹ã±ãŒã¹ã¯ä»¥åã®æ¹æ³ã§è§£æ±ºããç¶ããã§ããããïŒ
props
å ã«å«ããããšãã§ãããã®ä»¥å€ã®è¿œå ããŒã¿ãè¿ãå¿ èŠãããç¶æ³ã確èªããããšã«èå³ããããŸãã ãããŒãžããšã®åäœãããã«å¶åŸ¡ããããšããã€ã³ã©ã€ã³ã®èª¬æã¯å°ãææ§ã§ããã
å¿ èŠã«å¿ããŠåŸã§æ¡åŒµã§ããããã«ãã¡ãœãããå°æ¥çã«æ ¡æ£ããããšãéèŠã§ãã
ãšãŠãé¢çœããïŒ åœŒã¯
getInitialProps
代ããã«ãªãã®ã§ããããããããšãäžç·ã«ãªããŸããïŒ ããšãã°ãç§ãã¡ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãããŒã¿ãã§ããAPIã¯å ¬å ±ãµãŒãã¹ã§ãã ãããã£ãŠãã¯ã©ã€ã¢ã³ãåŽã®ããã²ãŒã·ã§ã³ã§ã¯ãã¯ã©ã€ã¢ã³ããAPIã¬ã€ã€ãŒãçŽæ¥åŒã³åºãããšãæåŸ ããŸãããSSRã§ã¯ãµãŒããŒããããåŒã³åºããŸãã ä»åŸããã®ãŠãŒã¹ã±ãŒã¹ã¯ä»¥åã®æ¹æ³ã§è§£æ±ºããç¶ããã§ããããïŒ
äžè¬ã«ããã®åäœã«ã¯ããã€ãã®æ¬ ç¹ããããŸããããšãã°ãäžçäžã®ç¹å®ã®é åããã®ãŠã©ãŒã¿ãŒãã©ãŒã«ã®ãã§ãããé
ããªãå¯èœæ§ããããŸãã getServerProps
ã¢ãããŒãã«ãããå¿çãããå¹ççã«ãã£ãã·ã¥ã§ããŸãã
ããã¯æ¬åœã«é¢çœããã§ãïŒ ãã£ãããã¢ã€ãã¢ïŒ
ããããå±éã«ã€ããŠæžå¿µããããŸã...
Nowã§ãã¹ãããŠãããšæ³åããŠã¿ãŸãããã
æåã®ãããã€ã¡ã³ãã§ã¯ãã¢ããªã±ãŒã·ã§ã³å
šäœããããã€ã¡ã³ãã«åºã¥ããŠæ§ç¯ãããããšã¯æããã§ãã
次ã«ãCMSã®äžéšã®ã³ã³ãã³ããå€æŽããSSGããŒãžã®ã¿ã®åæ§ç¯ãããªã¬ãŒããããšããŠããŸãããã¢ããªã±ãŒã·ã§ã³ã³ãŒãã¯å€æŽãããŠããŸããã
ããã«ã¢ã©ãŒã ã鳎ããŸãããã®å Žåããã«ããããªã¬ãŒãããšã次ã®2ã€ã®è§£æ±ºçãèããããŸãã
1ïŒãã¹ãŠããã£ãã·ã¥ããããããäœãåæ§ç¯ãããŸãããã³ãŒãã¯å€æŽãããŠããããäœãšããããŠããŸããã
2ïŒ --force
ãããšãããã¹ãŠããåæ§ç¯ãããŸãããSSGããŒãžã®åæ§ç¯ã®ã¿ãå¿
èŠã§ããã
_ãããã¯åãªã仮説ã§ããããã«ãã·ã¹ãã èªäœã«äŸåããŸã-Nextãã©ã®çšåºŠèªèããŠããã_
ããã¯ããããä»ã®ãã¹ãã£ã³ã°ãœãªã¥ãŒã·ã§ã³ã«åœ±é¿ãäžããã§ãããã
Nextèªäœã«ã¯.next/cache
ãŸã...ããã¯ãããã©ã®ããã«åé¿ããŸããïŒ
@joltmodeã¯ãåºæ¬çã«çŸåšãã¹ãŠã®éçãµã€ããžã§ãã¬ãŒã¿ãŒã«.next/cache
ã¯ãNowã§ã®å±ééã§ä¿æãããåå©çšãããŸãã çŸåšããã®å Žåããã£ãã·ã¥ïŒæœåšçã«https://zeit.co/blog/serverless-pre-renderingïŒã§getInitialPropsã䜿çšããŠããå¯èœæ§ãããããšã«æ³šæããŠãã ãããããã¯ããµãŒããŒã¬ã¹é¢æ°ã§åçã«ã¬ã³ããªã³ã°ããŠãããCDNã«ãã£ãã·ã¥ããŸããåäœã¯ãŸã å®å
šã«æ£åžžã§ããã getServerProps
ã䜿çšããŠãåŒãç¶ãæ©èœããŸãã
æ¬åœã«çŽ æŽãããã顧客ãããžã§ã¯ãã§Nextãã©ã®ããã«äœ¿çšããŠãããã«ããŸãé©åããã³ããŒãããã€ã©ãŒãã¬ãŒãã³ãŒããããã€ãåé€ããŸãã
èæ ®ãã¹ãããšã®1ã€ã¯ãgetStaticPropsãšgetServerPropsã®ååã§ããããããå°æ¥ã{props}ãšãã®ä»ã®æœåšçãªãªãã·ã§ã³ãè¿ãå Žåã* Propsã¯æ··ä¹±ããŸãããïŒ ãã¶ããgetStaticConfigurationãgetStaticSetupãgetStaticOptionsã¯ãã£ãšäžè¬çã§ããããïŒ
@kibsã®æ»ãå€ã¯ãåžžã«å°éå ·ã®åŠçæ¹æ³ã«é¢é£ããŠããŸãã ã§ããããããŒãã³ã°ã¯çŽ æŽãããimoã§ãã
ããã¯åã«çŽ æŽãããã§ãïŒ ããã¯ããã©ã€ããŒãWebã¢ããªãšãããã§ãã·ã§ãã«Webã¢ããªã®äž¡æ¹ãéçºããŠãããšãã«ãç§ãæè¿æã£ãŠããããŸãã¯èããããšãã§ãããã¹ãŠã®ãŠãŒã¹ã±ãŒã¹ãšããŒãºã解決ããŠããŸãã ããªãã¯ç§ãç§èªèº«ã®ãã€ããªãããµã€ããžã§ãã¬ãŒã¿ãŒãå§ããã®ã劚ããã ãã§ããããããšãïŒ
ãŸããæ°ããã¡ãœããã以åã®getInitialProps()
ããã³exportPathMap()
ãããåªããŠããããšã«é¢é£ããããšãã§ããŸãããã
ãããè©Šãã®ãåŸ ã¡ãããŸããïŒ
è£è¶³ïŒæåŸã®äŸã§ã¯ã
getServerProps()
context
ãã©ã¡ãŒã¿ããªãããã§ãã
è£è¶³ïŒæåŸã®äŸã§ã¯ãgetServerPropsïŒïŒã«ã³ã³ããã¹ããã©ã¡ãŒã¿ããªãããã§ãã
ä¿®çæžã¿ïŒ
ããã¯çŽ æŽãããã§ããïŒ TypeScriptãŠãŒã¶ãŒã®èŠ³ç¹ãããããŒãžã³ã³ããŒãã³ãã®éçã¡ãœãããšããŠgetStaticProps
ã getStaticPaths
ã getServerProps
ãã©ããçåã«æããŸãïŒçŸæç¹ã§ã¯getInitialProps
ïŒãæ£ããå
¥å/䜿çšããã®ãç°¡åã«ãªããŸãã
const Page: NextPage<Props> = (props) => ...
// Explicit types needed here
export const getStaticPaths: NextGetStaticPaths<Params> = () => ...
export const getStaticProps: NextGetStaticProps<Props, Params> = (context) => ...
export const getServerProps: NextGetServerProps<Props> = (context) => ...
export default Page
// vs.
const Page: NextPage<Props, Params> = (props) => ...
// Static method types come from NextPage<Props, Params>
Page.getStaticPaths = () => ...
Page.getStaticProps = (context) => ...
Page.getServerProps = (context) => ..
export default Page
@herrstuckiãã®ã¢ãããŒãã®åé¡ã¯ãããªãŒã·ã§ã€ã¯ãéåžžã«é£ãããªãããšã§ãïŒèªãïŒã»ãŒäžå¯èœïŒã ããã¯ãäžèŠãªã³ãŒãããã©ãŠã¶ã«éä¿¡ãããããšãæå³ããŸãã
@timneutkensã®è¯ãç¹âŠããããå¥ã®ãã¡ã€ã«ã¯ããã«æå³ããããŸãããïŒ ãããšãããã®ãããª_確å®ã«_ããªãŒãæºãããããšãã§ãããã®ã§ããïŒ
// This should all be removed in client-side code âŠ
import {fetchQuery, queryTag} from 'big-data-fetching-lib';
const query = queryTag`...`
export const getStaticProps = async () => ({ props: await fetchQuery(query) })
// Only this should be included client-side
export default (props) => ...
@herrstuckiã¯ç¢ºå®ã«ããªãŒã·ã§ã€ã¯ã§ããŸãããå¥ã®ãã¡ã€ã«ã
ãšãŠãé¢çœããïŒ åœŒã¯
getInitialProps
代ããã«ãªãã®ã§ããããããããšãäžç·ã«ãªããŸããïŒ ããšãã°ãç§ãã¡ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãããŒã¿ãã§ããAPIã¯å ¬å ±ãµãŒãã¹ã§ãã ãããã£ãŠãã¯ã©ã€ã¢ã³ãåŽã®ããã²ãŒã·ã§ã³ã§ã¯ãã¯ã©ã€ã¢ã³ããAPIã¬ã€ã€ãŒãçŽæ¥åŒã³åºãããšãæåŸ ããŸãããSSRã§ã¯ãµãŒããŒããããåŒã³åºããŸãã ä»åŸããã®ãŠãŒã¹ã±ãŒã¹ã¯ä»¥åã®æ¹æ³ã§è§£æ±ºããç¶ããã§ããããïŒäžè¬ã«ããã®åäœã«ã¯ããã€ãã®æ¬ ç¹ããããŸããããšãã°ãäžçäžã®ç¹å®ã®é åããã®ãŠã©ãŒã¿ãŒãã©ãŒã«ã®ãã§ãããé ããªãå¯èœæ§ããããŸãã
getServerProps
ã¢ãããŒãã«ãããå¿çãããå¹ççã«ãã£ãã·ã¥ã§ããŸãã
ãã¡ããã§ãããReactãµãŒããŒãžã®RTTããŸã£ããåé¿ããããšã«ã€ããŠè©±ããŠããŸãã ãµãŒããŒããã®SSRåºåãCDN /ãã£ãã·ã¥ãµãŒããŒãããã·ã«ãã£ãã·ã¥ãããŠããå ŽåãèããŠã¿ãŸãã ããããå¥ã®APIã¬ã€ã€ãŒïŒWeb /ã¢ããª/ãã¹ãŠã®ã¯ã©ã€ã¢ã³ãã«å ±éïŒãçŽæ¥åŒã³åºãã¯ã©ã€ã¢ã³ãããã²ãŒã·ã§ã³ã®ããŒã¿ãã§ãããšçµã¿åããããšããã©ãã£ãã¯ã®å€ãã·ããªãªã§Next.jsãµãŒããŒã¬ã€ã€ãŒãããã»ã©ã¹ã±ãŒã«ã¢ããããå¿ èŠããªããªããŸãã
ãŠã©ãŒã¿ãŒãã©ãŒã«ãã§ããã®ãã€ã³ãã¯ç解ããŠããŸãããæ¶è²»è ãNextãµãŒããŒãããŒã¿ãœãŒã¹ã§ã¯ãªãSSRã¬ã€ã€ãŒãšããŠæ±ãããšãã§ããããã«ãããšãã¹ã±ãŒãªã³ã°ã®ã»ããã¢ãããå€§å¹ ã«æ¹åãããŸãã
ãšãŠãé¢çœããïŒ åœŒã¯
getInitialProps
代ããã«ãªãã®ã§ããããããããšãäžç·ã«ãªããŸããïŒ ããšãã°ãç§ãã¡ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãããŒã¿ãã§ããAPIã¯å ¬å ±ãµãŒãã¹ã§ãã ãããã£ãŠãã¯ã©ã€ã¢ã³ãåŽã®ããã²ãŒã·ã§ã³ã§ã¯ãã¯ã©ã€ã¢ã³ããAPIã¬ã€ã€ãŒãçŽæ¥åŒã³åºãããšãæåŸ ããŸãããSSRã§ã¯ãµãŒããŒããããåŒã³åºããŸãã ä»åŸããã®ãŠãŒã¹ã±ãŒã¹ã¯ä»¥åã®æ¹æ³ã§è§£æ±ºããç¶ããã§ããããïŒäžè¬ã«ããã®åäœã«ã¯ããã€ãã®æ¬ ç¹ããããŸããããšãã°ãäžçäžã®ç¹å®ã®é åããã®ãŠã©ãŒã¿ãŒãã©ãŒã«ã®ãã§ãããé ããªãå¯èœæ§ããããŸãã
getServerProps
ã¢ãããŒãã«ãããå¿çãããå¹ççã«ãã£ãã·ã¥ã§ããŸãããã¡ããã§ãããReactãµãŒããŒãžã®RTTããŸã£ããåé¿ããããšã«ã€ããŠè©±ããŠããŸãã ãµãŒããŒããã®SSRåºåãCDN /ãã£ãã·ã¥ãµãŒããŒãããã·ã«ãã£ãã·ã¥ãããŠããå ŽåãèããŠã¿ãŸãã ããããå¥ã®APIã¬ã€ã€ãŒïŒWeb /ã¢ããª/ãã¹ãŠã®ã¯ã©ã€ã¢ã³ãã«å ±éïŒãçŽæ¥åŒã³åºãã¯ã©ã€ã¢ã³ãããã²ãŒã·ã§ã³ã®ããŒã¿ãã§ãããšçµã¿åããããšããã©ãã£ãã¯ã®å€ãã·ããªãªã§Next.jsãµãŒããŒã¬ã€ã€ãŒãããã»ã©ã¹ã±ãŒã«ã¢ããããå¿ èŠããªããªããŸãã
ãŠã©ãŒã¿ãŒãã©ãŒã«ãã§ããã®ãã€ã³ãã¯ç解ããŠããŸãããæ¶è²»è ãNextãµãŒããŒãããŒã¿ãœãŒã¹ã§ã¯ãªãSSRã¬ã€ã€ãŒãšããŠæ±ãããšãã§ããããã«ãããšãã¹ã±ãŒãªã³ã°ã®ã»ããã¢ãããå€§å¹ ã«æ¹åãããŸãã
CDNãåçå¿çããµããŒãããŠããå Žåããã®æ°ããåäœã¯ãå®éã«å®å šãªçµæãCDNã«ãã£ãã·ã¥ã§ããããšãæå³ãããšèª€è§£ããŠãããšæããŸãã ããã¯ã以åã¯getInitialPropsã§ã¯ç¢ºå®ã«å¯èœã§ã¯ãããŸããã§ããã
@timneutkensã«ããªã¢ã§éãã§ã babel-plugin-preval
ã³ãŒããgetStaticProps
ã«ç§»æ€ããããšããŸããã fs
åé¡ãçºçããŸããã
./pages/blog/
ãã£ã¬ã¯ããªã®.mdãã¡ã€ã«ãèªã¿åã£ãŠã«ãŒããããã¹ãŠã®æçš¿ãå«ãããã°ã®ã€ã³ããã¯ã¹ããŒãžãäœæããããšããŠããŸãã
import React from 'react';
import Link from 'next/link';
import fs from 'fs-extra';
const Index = ({ posts }) => (
<div>
Hello World. <Thing msg="hello" />
<Link href="/thing">
<a>About</a>
</Link>
{posts.map(p => (
<div key={p.title}>{p.title}</div>
))}
</div>
);
Index.getStaticProps = async () => {
const items = await fs.readdir('./pages/blog');
items.forEach(path => /* .... do some stuff ... */ )
return { props: { posts: items } };
};
export default Index;
ãã®ã³ãŒãã¯ãã®ãšã©ãŒã«ã€ãªãããŸãïŒ
Module not found: Can't resolve 'fs' in '/Users/jared/Downloads/nextjs-typescript-template/node_modules/fs-extra/lib'
Razzleã®IIRCããã®ãšã©ãŒã¯webpackã®ãã¡ã€ã«ã·ã¹ãã ã¹ã¿ãïŒãŸãã¯ãã®æ¬ åŠïŒã«é¢ä¿ããŠããŸãã ãããwebpackæ§æã«è¿œå ããããšã§ãRazzleã§ãããä¿®æ£ããããšããããšæããŸãã
node: {
fs: "empty";
}
ãã®next.config.jsãè©ŠããŸãããããšã©ãŒãæ¶ããã ãã§ãã fs
/ fs-extra
ãå®éã«ã¯æ©èœããªãããæ©èœãããããããã¹ãæ©èœããªãããã«èŠããŸãïŒç§ã«ã¯ããããŸããïŒã ããã«ã€ããŠäœãèãã¯ãããŸããïŒ
ç§ã®ä»ã®è³ªåã¯ãããäžè¬çã«ã¯ã getStaticProps
ã§ã€ã³ããŒããšrequireã䜿çšããããã®ãã¹ããã©ã¯ãã£ã¹ãäœã§ãããšæ³åãããã§ãã ç§ãééã£ãŠããªãå Žåãäžèšã®ã¹ããããã¯Reactã«fs-extra
ã§ã€ã³ããŒãããããšããŸãã??ã ãããã£ãŠãã€ã³ããŒãããã®ããã«ã€ã³ã©ã€ã³èŠæ±ã«å€æŽããæ¹ãããã§ããããïŒ
js
Index.getStaticProps = async () => {
const fs = require('fs-extra'); // only require when needed at SSG
const props = await fs.readdir('./pages/blog');
return { props: { posts } };
};
CDNãåçå¿çããµããŒãããŠããå Žåããã®æ°ããåäœã¯ãå®éã«å®å šãªçµæãCDNã«ãã£ãã·ã¥ã§ããããšãæå³ãããšèª€è§£ããŠãããšæããŸãã ããã¯ã以åã¯getInitialPropsã§ã¯ç¢ºå®ã«å¯èœã§ã¯ãããŸããã§ããã
ãããç§ã¯ããªããèšã£ãŠããããšãç解ããŠãããšæããŸãã ããã¯ãæåã®SSRäžä»£ã®getServerProps
ãäžæã®ãšã³ããã€ã³ããäœæããããšãæå³ããŸããïŒã³ã³ãã³ãã¢ãã¬ã¹å¯èœãªããã·ã¥ã§ãããããURLã§ãCDNã«ãã£ãã·ã¥ã§ããå¯èœæ§ããããŸããïŒ ããã®å¯äžã®æ¬ ç¹ã¯ããã£ãã·ã¥ãNext以å€ã®ã¢ããªïŒandroid / iosïŒãšNextã¢ããªã®éã§å
±æã§ããªãããšã§ãã ããã«ãå€éšããŒã¿ãœãŒã¹ã®å Žåããã£ãã·ã¥å¶åŸ¡ãã£ã¬ã¯ãã£ãã¯ã¢ããã¹ããªãŒã ã§ãããããã§ã¯NextãããŒã¿ã®æäŸãæ
åœãããããçæãããããŒã¿ãšã³ããã€ã³ãçšã«APIãŸãã¯å°éå
·ãæå®ããå¿
èŠããããŸãã
@jaredpalmer https://github.com/zeit/next.js/issues/9524#issuecomment -558628066ïŒä¿¡é Œã§ããããªãŒã·ã§ã€ã¯å¯èœæ§ã«é¢ããæžå¿µãå«ãïŒã¯ãå®å šã«å¥åã«ã³ã³ãã€ã«ãããå¥åã®ãã¡ã€ã«ãæããŸããã¯ã©ã€ã¢ã³ããã³ãã«ã³ãŒãïŒ äŸãã°
pages/
foo.js
foo.data.js (<- exports getStaticProps etc.)
or:
pages/
foo.js
pages-data/
foo.js (<- exports getStaticProps etc.)
@jaredpalmerã®ããªãŒã·ã§ã€ã¯ã¯ãã«ããªã¢ã§ã¯ãŸã å®è£ ãããŠããŸããã
ãã€ãã®ããã«ããã¹ãŠã®ããšãããããšãã Next.jsã¯ãäœæ¥ããã®ã«çµ¶å¯Ÿçãªåã³ã§ãããåã«ãèšã£ãããã«ãã»ãŒãã¹ãŠã®æ©èœãªãªãŒã¹ã§ã管çããã³ãŒãããŒã¹ã®ãµã€ãºã_çž®å°_ã§ããŸãã ãããã
ãã®RFCã¯ãæžãããŠããããã«ãå€ãã®ã¢ããªã±ãŒã·ã§ã³ã«ããã«åœ¹ç«ã€ãããæ¹å€ããã®ã¯é£ããã§ãã ãã ããåæãããã©ããããããªã1è¡ã«å¯ŸåŠããããšæããŸãã
ã
getStaticPaths
ã¯ãexportPathMap
ãæã€å¿ èŠæ§ã眮ãæããããŒãžããšã«æ©èœããŸããã
äžéšã®ã¢ããªã±ãŒã·ã§ã³ã§ã¯ããã«ãæã«ã«ãŒããç¥ãããšãéçŸå®çãŸãã¯äžå¯èœã§ãã ããã€ãã®äŸã¯æ¬¡ã®ãšããã§ãã
ãã®ãããªããŒãžã®ã«ãŒãã¯ãããã/entity-name/entity-id
ã®åœ¢åŒã«ãªãã router.push('/customers/[customerId]', '/customers/baer')
ãããªããšãã§ããã®ã§ãNextã®åçã«ãŒãã¯éåžžã«ããŸãæ©èœããŸãã ãŸã åé¡ããããŸãã ServeãNetlifyãNGINXãªã©ã䜿çšããŠãããã®ãã¡ã€ã«ãéçã«æäŸããå Žåã¯ããŠãŒã¶ãŒãããŒãžãæŽæ°ãããšãã«404ãååŸããªãããã«ãäžé£ã®ãªãã€ã¬ã¯ããçæããå¿
èŠããããŸãã exportPathMap
ãå¿
èŠã§ãã
以äžã¯ãç§ãå®æçã«äœæ¥ããŠããã³ãŒãããŒã¹ãããã»ãŒçŸç¶ã®ãŸãŸã³ããŒãããŠããŸãã
const buildServeConfig = redirects => {
const config = {
public: `dist`,
trailingSlash: true,
rewrites: redirects
};
const outputPath = `${__dirname}/serve.json`;
fs.writeFile(outputPath, JSON.stringify(config, null, 2), err => {
if (err) {
throw err;
}
// eslint-disable-next-line no-console
console.log(`Generated: ${outputPath}`);
});
};
...
exportPathMap: function(defaultPathMap, { dev, outDir }) {
const redirects = Object.entries(defaultPathMap)
// No need to create a redirect rule for `/dirname/` or `/dirname/index.html`
.filter(([url]) => url !== `/` && url !== `/index`)
.map(([url, { page }]) => ({
// Replaces /[customerId] with /:customerId
source: url.replace(/]/g, ``).replace(/\[/g, `:`),
destination: `${page}/index.html`
}));
// By default, the routes are sorted such that a route like `/order/:orderId`
// comes before `/order/new`. Since the `:orderId` portion of `/order/:orderId`
// is a wildcard, the route `/order/new` will be a match and consider `new`
// as a value for `:orderId`. To get past this, we sort the redirects by the
// number of parameters in ascending order.
const sortedRedirects = [...redirects].sort(
(currentRedirect, nextRedirect) =>
currentRedirect.source.split(`:`).length >
nextRedirect.source.split(`:`).length
);
buildServeConfig(sortedRedirects);
return defaultPathMap;
}
ãã®RFCãAPIãéæšå¥šã«ãããåé€ãããããªãããšãç解ããŠããŸãããŸãããã«ããã£ã¬ã¯ããªããã©ããŒã¹ããããšã§ãããã®ãªãã€ã¬ã¯ãããã«ãã§ããããšãèªèããŠãããããéæšå¥šã«ãªã£ãå Žåã§ããåªãããšã¹ã±ãŒããããããããŸãã ããããããã¯ã getStaticPaths
ã®å¿
èŠæ§ãåãé€ããããã§ã¯ãããŸããã
ç¹°ãè¿ãã«ãªããŸããããã®ãããžã§ã¯ãã®å®è¡æ¹æ³ã«é æ ®ããŠããã ãããããšãããããŸã
getStaticProps
/getStaticPaths
ãšgetServerProps
çžäºã«æä»çã§ããïŒ ã€ãŸããããŒããäºåã¬ã³ããªã³ã°ããããŒããåçã«ããããšã¯å¯èœã§ããããïŒ
ããã1ã€ã¯éççæã§ããã1ã€ã¯ãµãŒããŒåŽã¬ã³ããªã³ã°ã§ãã
ããã«ãããNextã«ç§»è¡ããåã«GatsbyããèŠéããŠãã倧ããªåé¡ã®1ã€ãä¿®æ£ãããŸãã
ã¢ããªã·ãã¯ïŒæ°çŸkbsïŒã®JSONãã¡ã€ã«ããããããããããŒã¿ãååŸããŠãããŒãžãå€æŽããã«ã¬ã³ããªã³ã°ããŸãã Gatsbyã§ã¯ãJSONãã¡ã€ã«ãGraphQLã¹ããŒãã«ããŒãããããã«å¯ŸããŠã¯ãšãªãå®è¡ããç¹å®ã®ããŒãžãã¬ã³ããªã³ã°ããããã«å¿
èŠãªããŒã¿ã®ã¿ãååŸããŸããã Nextã§ã¯ããããè¡ãããã®æãç°¡åã§ã¯ãªãŒã³ãªæ¹æ³ã¯import monolith from './monolith.json'
ã§ããããŠãŒã¶ãŒã¯JSONãã¡ã€ã«å
šäœãããŠã³ããŒãããå¿
èŠããããŸãã
ãã®RFC100ïŒ ã¯ãã®ãŠãŒã¹ã±ãŒã¹ã«å¯Ÿå¿ããGatsbyãåªããŠããé åã§Gatsbyãšåçã«è¿ã¥ãããã®æ¬¡ã®ã¹ãããããããããŸãïŒæããã«ãGatsbyã¯ã©ã³ã¿ã€ã SSRãå®è¡ã§ããªããããéçãã«ãã¿ã€ã ã¬ã³ããªã³ã°ã«ã€ããŠã®ã¿èª¬æããŸãïŒ
@ timneutkens ãRFCãããããšãïŒ
æè¿@rauchgãšè©±ãåã£ãNext.jsã®ãŠãŒã¹ã±ãŒã¹ããããŸãã
Next.jsã¯ãéåžžã«ã¹ã ãŒãºãªDXãšããã€ãã®åŠ¥åœãªããã©ã«ããæäŸããŸãã ãã®ãããã¯ã©ã€ã¢ã³ãåŽã§ã®ã¿ã¬ã³ããªã³ã°ãããã¢ããªã±ãŒã·ã§ã³ã§ããã¹ããŒãTVã¢ããªã«Next.jsã䜿çšããããšã«èå³ããããŸãã
ã¹ããŒãTVã¢ããªã¯ãTVã®ãã©ãŠã¶ãšã³ãžã³ã«ãã£ãŠå®è¡ãããã»ãŒå€å žçãªWebã¢ããªã§ãã
éèŠãªã®ã¯ããã³ãã«ãTVããã€ã¹èªäœã«ãã£ãŠéçã«ãã¹ããããŠããããµãŒããŒããããŒããããŠããªãããšã§ãã ãããã£ãŠãSSRãªãã·ã§ã³ã¯äœ¿çšã§ããŸããïŒNode.jsã¯ãããã®ç®çã§éçºè ã«å ¬éãããŸããïŒã ããããã¢ããªèªäœã¯åçã§ãïŒããšãã°ãNetflixïŒã
ãããã£ãŠãéçWebãµãŒããŒã«ãã£ãŠãã¹ããããŠããSPAãå®è¡ããå¿ èŠããããŸãã
ç§ãç解ããŠããããã«ã getServerProps
ïŒãŸãã¯getInitialProps
ïŒãå®å
šã«ãªããã¢ãŠããããšãSSRãåé¿ããã®ã«åœ¹ç«ã¡ãŸãã ããããã¯ã©ã€ã¢ã³ãã§ã®åçã¬ã³ããªã³ã°ã¯ã©ããªããŸããïŒ ãããŠããã®å Žåã®ã«ãŒãã£ã³ã°ã¯ã©ãã§ããïŒ ãã®RFCã«ãããšã@ timneutkens ã
PSåå¥ã«è°è«ããæ¹ããããšæãããå Žåã¯ããã®ãŠãŒã¹ã±ãŒã¹ã®åé¡ãäœæã§ããŸãã
@grushetskyå¥ã®åé¡ãäœæã§ããŸããã ããã¯ãRFCã§è°è«ãããŠãããã®ãšã¯ãŸã£ããç°ãªã質åã§ãð
@timneutkensãã®RFCã®çŽæã¯ãç§ãNextã«éåžžã«è奮ããããšã®1ã€ã§ãã æ確ã«ããããã«ã getInitialProps
ããŸã ååšããŸãããïŒ
æ£ãã@outdooricon - getInitialProps
ã¯ãåœé¢ã®éæ®ããŸãã
RFCã«ãããšïŒ
ãã®RFCã¯ãAPIã®è¿œå ã«ã€ããŠã®ã¿èª¬æããŠããŸãã ãã¹ãŠã®æ°æ©èœã¯å®å šãªäžäœäºææ§ãããã段éçã«æ¡çšã§ããŸãã ãã®RFCã¯éæšå¥šãå°å ¥ããŠããŸããã
çŽ æŽãããRFCãããã«éåžžã«è奮ããŠããŸãïŒ
ç§ã¯ç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã«é¢é£ããŠgetServerProps
ã«ã€ããŠèããŠããŠãçµæããã£ãã·ã¥ã«å
¥ããŠããŸãã ããã¯APIãšã³ããã€ã³ãã«å€æãããçµæãå°éå
·ãšããŠã³ã³ããŒãã³ãã«é
ä¿¡ããããããçµæãReduxãGraphQLãã£ãã·ã¥ãªã©ã®ã¯ã©ã€ã¢ã³ãåŽã®å€éšãã£ãã·ã¥ã«é
眮ããèŠå®ã®æ¹æ³ã¯ãããŸããïŒ
getInitialProps
ã¯éçã§éåæã§ãããããæ£ããç解ããŠããã°ãNextã«ã¯ãã³ã³ããŒãã³ããåããŠã¬ã³ããªã³ã°ããåã«ãå®äºããã®ãåŸ
ã€æ©äŒããããŸãã ããã«ãããå€éšãã£ãã·ã¥ã«ç©äºãå
¥ããããšãã§ããŸãã getServerProps
ã¯ãµãŒããŒäžã§å®è¡ããããããããã¯åœãŠã¯ãŸããŸãããã³ã³ããŒãã³ãã®ã©ã€ããµã€ã¯ã«ã§ãã£ãã·ã¥ã«ããŒã¿ãé
眮ãããšããããšã¯ãããŒã¿ããŸã ãã£ãã·ã¥ã§å©çšã§ããªãã¬ã³ããªã³ã°ãå¿
èŠã§ããããšãæå³ããŠããããã§ãã ãå°éå
·ã§å©çšã§ããå Žåã§ãïŒ
ãã¡ããããã¯æå³çãªãã®ã§ãããã¢ãããŒããæ¬ ããŠãããããããŸãããããããèæ ®ãããŠãããã®ã§ãããã©ãããå°ãããšæããŸããã
ç·šéïŒããã¯getStaticProps
ãåœãŠã¯ãŸããšæããŸãã ð
ã©ããã§èŠéãããããããŸããããã³ã³ãã³ãããã£ãã·ã¥ãããŠããã®ã«ãdbã§æŽæ°ãããããæ°ããããã°æçš¿ãäœæããããããç¶æ³ãã©ã®ããã«åŠçããŸããïŒ æ°ãããã«ããèªåçã«è¡ãå¿ èŠããããŸããïŒ ãã¶ãããã ã
åãã«ïŒ ãã°ãããææ¡ã§ããã»ãšãã©ã®äººã®ãŠãŒã¹ã±ãŒã¹ã§exportPathMaps
ã倧å¹
ã«äžåã£ãŠããŸãã æ¬åœã«ãããããã§ãã ããã¯èšã£ãŠããã«ãŒãã®åœéåã§ã©ã®ããã«æ©èœãããããšãã§ããããç解ããã®ã«èŠåŽããŠããŸãã
i18nãã¬ãã£ãã¯ã¹ä»ãã«ãŒããåŠçããæ¹æ³ã«é¢ããææ¡ã¯ãããŸããïŒ ç§ã®ç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã§ã¯ãcountry-langãã¬ãã£ãã¯ã¹ãšURLãç°ãªãããŒãžã§æ°åãæ§ç¯ããå¿ èŠããããŸãã
/nl/brillen
/gb/glasses
/es/gafas
...
ããªãã®äŸã®ããã«ïŒ /blog/[id].js
ïŒãURLã®ãã¬ãã£ãã¯ã¹ãããç¥ãããŠããå Žåã getStaticPaths
ã¯æ¬åœã«åœ¹ç«ã€ããã§ãã ããããåçãã¬ãã£ãã¯ã¹ïŒcountry-langïŒãšåçãã¹ã®äž¡æ¹ã䜿çšããŠã«ãŒãã¬ãã«ã§ãã¹ãçæããå¿
èŠãããå Žåã getStaticPaths
å®è£
ã¯ã©ã®ããã«èŠãããšæããŸããïŒ
@reaktivo pages/[lang]/blog/[id].js
-> getStaticPaths
ãéçã«ã¬ã³ããªã³ã°ãããã¹ãŠã®URLãæäŸããŸãã
@timneutkensããããã€å©çšå¯èœ/ãã¹ãå¯èœã«ãªããã«ã€ããŠäœãèãã¯ãããŸããïŒ
äžè¬ã«ãETAã¯æäŸããŸãããããã¯ããœãªã¥ãŒã·ã§ã³ãæ£ããããšã確èªããããã«ãæ¬çªã¢ããªã«å¯ŸããŠæ©èœãåºç¯å²ã«ãã¹ãããããã§ãã
ãã®æ¹åã«ããããç¶æãããŠããªãããã§ããã¯ã¹ãããžã§ã¯ãïŒç§ä»¥å€ã¯èª°ã䜿çšããªãreact ssgïŒãå®å šã«å»æ¢ããããšã«ãªããŸãã Next.jsããã®äžè¶³ããŠããéšåãè¿œå ããŠããã®ãèŠãã®ã¯çŽ æŽãããã§ãïŒ
çåãæããã«ããããšæããŸãã ã¯ãŒããã¬ã¹ã®ãããªCMSã®äœ¿çšãæ€èšããŠããŸãã ç§ãç解ããŠããããã«ãgetStaticPathsã¡ãœããã䜿çšãããšããã¹ãŠã®æçš¿ããã§ããããŠã次ã®ãããªãªã¹ããæž¡ããŸãã
export async function getStaticPaths () {
return [
  // This renders / blog / hello-world to HTML at build time
{params: {slug: "hello-world"}}
];
}
åæçš¿ã®ã¹ã©ãã°ã¯ãã³ã³ãã³ãããã§ããããããã«getStaticPropsã¡ãœããã§äœ¿çšãããŸãã
ããã¯npmãã«ãã§çºçããŸãã
ç§ã®è³ªåã¯ããã«ãåŸã«è¿œå ãããæ°ããæçš¿ã«ã€ããŠã§ãã
getStaticPropsã¡ãœããã䜿çšããŠããã®æ°ããæçš¿ãã¹ã©ãã°ã§ãã§ããããŸããïŒ
ãã®æ°ããæçš¿ã«ã¯ãåã®ãã«ãã®ãããª.htmlãã¡ã€ã«ãå«ãŸããŸããïŒ
ç§ã¯æ¬¡ã®ä»äºãããã®ã倧奜ãã§ãããã€ãã®ãããžã§ã¯ãã§ããã¯ãšãŠãè¯ããšæããŸãã
çŽæ¥é¢ä¿ãããã®ã¯ãããŸãããããµããŒãã¯ç§ã®è³ªåã«äžèŽããçããç§ã«äžããããšãã§ããŸããã
ããã§ææ¡ããã®ã¯è§£æ±ºçãããããŸãããããããŸã§ã®éãWebhookã®å€æŽã«åºã¥ããŠJAMSTACKãæ§ç¯ããããã«nextJSãäœæããããšã¯ã§ããŸããã
getInitialPropsãããã°ããµãŒããŒã§ã¬ã³ããªã³ã°ãããŸãã
ããã§ãªãå Žåãç§ã¯CDNåãããŠããã ãã§ãããäºåã¬ã³ããªã³ã°ãªãã§ã¯ããã§ã¯ãããŸãããïŒ ãããŠãXHRãæ»ã£ãŠããªãéããããŒãžã«ã¯ã³ã³ãã³ãããããŸããïŒbye-bye SEOïŒ
nextJSã䜿çšããJamstackã®å®è¡äŸã¯ãããŸããïŒnetlifyã§å®è¡ã§ããŸãã
ããããšãã
ã¢ã³ãã¬ã¢ã¹
ã¡ãã£ãš@ ScreamZ-ãã®å€æŽã¯ãå®å
šã«éçãªãµã€ããnextjsã§æ§ç¯ã§ããããã«ãããã®ã ãšæããŸãã é·ãéã next export
ã䜿çšããŠnextjsãµã€ããéçã«ã³ã³ãã€ã«ããããšãã§ããŸããããããã§ãgetInitialProps
ã䜿çšããŠã¯ã©ã€ã¢ã³ãåŽã®ã«ãŒãé·ç§»ã«é¢ããããŒã¿ããã§ããããŸãã getStaticProps
ã䜿çšããæ©èœã䜿çšãããšãè¿œå ã®ããŒã¿ããã§ããããã«ã¯ã©ã€ã¢ã³ãåŽã®é·ç§»ãå®è¡ã§ããŸãã getStaticProps
ã§ãã§ããããããã¹ãŠã®ããŒã¿ã¯ããã«ãæã«1åãã§ãããããæŽæ°ãããŸãããåæ§ç¯ããªãéããã©ã€ããµã€ãã ããã¯ããŒã¿é§ååéçãµã€ãã®å€å
žçãªã¢ãŒããã¯ãã£ã§ãããWebhookãä»ããŠããŒã¿ãœãŒã¹ããã¹ãã«ãªã³ã¯ããããŒã¿ãœãŒã¹ãå€æŽããããããµã€ããåæ§ç¯ããããã«ãã¹ãã«æ瀺ããŸãã
å®å šã«éçãªnextjsWebãµã€ãã®æ¢åã®äŸã¯ãããããããnetlifyã§nextjsãµã€ããå®è¡ããã®ã¯ç°¡åã§ãã ç§ã®äŒç€Ÿã®ãŠã§ããµã€ãã¯çŸåšnextjsã§å®è¡ãããŠãããnetlifyã«ãã£ãŠãã¹ããããŠããŸãããããè¯ãäŸã«ãªãããšãé¡ã£ãŠããŸãã
zeitã®ãã¹ãã£ã³ã°ãµãŒãã¹ã匷ãæ€èšãã䟡å€ãããããšã¯æ³šç®ã«å€ããŸãã äŸ¡æ Œã¯éåžžã«äŒŒãŠãããnextjsãµã€ããšã®çµ±åã¯ä»ã«é¡ãèŠãŸãã-æåéãäœãæ§æããå¿ èŠã¯ãããŸãããgithubããªã³ã¯ããã ãã§ãzeitã®ãã¹ãã£ã³ã°ã¯nextjsãå®è¡ããŠããããšãèªèããèªåçã«æ§æããŠãããã€ããŸããã¹ãŠã®ã
ããã¯æ±ºããŠåºåã§ã¯ãããŸãããç§ã¯zeitã®ããã«åããŠããŸããããã æ¬ç©ã®æ¿èªã§ãã ããªãã¯çµ¶å¯Ÿã«ãããnetlifyã§åäœãããããšãã§ããŸãããããŠç§ã¯èšŒæ ãšããŠããã€ãã®ãµã€ãã®ããã«å人çã«æã£ãŠããŸãã ãã ããnextjsãã©ã®ããã«æ©èœããããå®å šã«ç解ããå¿ èŠããããnetlifyã§ã¹ã ãŒãºã«å®è¡ã§ããããã«ãã¹ãŠãæ£ããæ§æãããŠããããšã確èªããå¿ èŠããããŸãã nextjsãµã€ãã§æãã·ã³ãã«ã§ç¢ºå®ãªãã¹ãã£ã³ã°ããæ¢ãã®å Žåã¯ãzeitã®ãã¹ãã£ã³ã°ãè©ŠããŠã¿ãŠãã ããã
@jescalanãã®çŽ æŽãããå ±æãããããšãðð»
Publish directory
ã䜿çšããŠout
ãã©ã«ããŒãæå®ã§ãããããnetlifyã§NextJSã䜿çšããŠãåé¡ã¯ãããŸããã ããããzeit Nowã§ã¯ãèšãæ¹æ³ã¯ãããŸãããSSRã䜿çšããã«ã next export
䜿çšããŠéçã«ãã£ã±ãã«ããŠãã ããã
@ScreamZããã¯äžçš®ã®çå®ã§ããããå®å
šãªéçããµã€ããã©ã®çšåºŠæ£ç¢ºã«å®çŸ©ãããã«ãã£ãŠç°ãªããŸãã ããªãã䜿çšããŠããå Žåã¯getStaticProps
ãã¡ã€ãã®ãã¹ãã£ã³ã°ãµãŒãã¹ã§ããã¹ãŠã®ããŒãžã®ããã«ãããªããåŸããã®ãå¹æçã«ãããå®è¡ãããªãå Žåã§ããéçãªãµã€ãã«çããnext export
æã€ãã¹ãŠã®ããŒãžããã getStaticProps
ã¯ããµã€ãããããã€ããããšãã«ã®ã¿æ§ç¯ããããã®åŸCDNããçŽæ¥æäŸãããŸãã
äž»ãªéãã¯ãç§ãç¥ãéããzeitã®ãã¹ãã£ã³ã°ã§ãã¹ãŠã®ããŒãžã匷å¶çã«éçã«ããæ¹æ³ããªãããšã§ãïŒç·šéïŒzeitã¯æè¿ã exportPathMap
ãå«ãæ§æãæã€ãã¹ãŠã®ãµã€ããå®è¡ãããããã«å€æŽããŸããå®å
šã«éçãªãµã€ããªã®ã§ãããã¯ãã¯ãçå®ã§ã¯ãããŸããïŒã getStaticProps
ããŒãžã¯ã next export
ã«ãã£ãŠçæãããããŒãžãšãŸã£ããåãããã«åäœããŸããããŒãžã®åäžã®éçã³ããŒã¯ãããããããã³ã«CDNããçŽæ¥æäŸãããŸãã ãã ãã getServerProps
ãŸãã¯getInitialProps
ã䜿çšããŠäžéšã®ããŒãžãå®è¡ããããšãã§ãããããã¯ãµãŒããŒã§ã¬ã³ããªã³ã°ãããããŒãžãšããŠåäœããŸãã å人çã«ã¯ãããã¯ã¡ãªããã ãšæããŸããSSRã«ãŒããå¿
èŠãªå Žåã¯ãå¥ã®ããŒã¿ãã§ããæ¹æ³ã䜿çšããã ãã§ããã®åäžã«ãŒããSSRã«ãªããä»ã®ãã¹ãŠã®ã«ãŒãã¯éçãªãŸãŸã«ãªããŸãã
@jescalanããããšãã
ãããã£ãŠããããå®è£ ãããã®ãåŸ ã€å¿ èŠããããŸãããããŸã§ã®éãéçã«netlifyã䜿çšããŸãã
SSGæ§æã«é¢ãã話ã¯ãããŸããïŒ å
·äœçã«ã¯ãå
±æãã«ãã¢ãŒãã£ãã¡ã¯ãã䜿çšãããã®ã§ãããQA /補åã®æ§æãç°ãªãnext export
ãå®è¡ããŸãã ãããã®æ§æå€ã¯ã getStaticProps
ã§ã®ã¿èªã¿åãããŸãã ããã¯serverRuntimeConfig
ãŸãã¯publicRuntimeConfig
ãŸãã¯process.env
çŽæ¥äœ¿çšããŸããïŒ
@ScreamZ @jescalan @Timerãšäžç·ã«Nowã§zero-config next export
ãµããŒããéå§ããŸããïŒåœŒã¯ãã¹ãŠã®ã¯ã¬ãžããã«å€ããŸãïŒã ã§ãããïŒ
"build": "next build && next export"
ãããŠãããã¯èªåçã«æ©èœããŸãã
ã©ããªããæããŠãã ããð
ãããç§ã¯ãµããŒããæ±ãã人ã§ããããããŠåœŒãã¯ããããŸã å®è£ ãããŠãããšç§ã«èšããŸããð ç§ãèŠãéããããªãã¯configã§ãšã¯ã¹ããŒãããããå®çŸ©ããå¿ èŠããããŸããïŒ
@ScreamZããããäžèšã®ããã«next build && next export
ãè¿œå ããã ãã§ãæ©èœããŸãã
@timneutkens getInitialProps
ãgetServerProps
ã«çœ®ãæããå Žåã§ãã Server Pre Rendering
ãæå¹ã«ããã«ã¯ãæ§æãã¡ã€ã«ã«target: 'serverless'
ãè¿œå ããå¿
èŠããããŸããïŒ ããããšãã
ã©ãããã°ããããè©Šãããšãã§ããŸããïŒ
ã©ãããã°ããããè©Šãããšãã§ããŸããïŒ
ãããã®ã¡ãœããã¯ãã¹ãŠãèªèãããããã«çŸåšunstable_
ãã¬ãã£ãã¯ã¹ãå¿
èŠã ãšæããŸãã
äŸïŒ unstable_getStaticProps
@timneutkens
@ScreamZ @jescalan @Timerãšäžç·ã«Nowã§zero-config
next export
ãµããŒããéå§ããŸããïŒåœŒã¯ãã¹ãŠã®ã¯ã¬ãžããã«å€ããŸãïŒã ã§ãããïŒ"build": "next build && next export"
ãããŠãããã¯èªåçã«æ©èœããŸãã
ã©ããªããæããŠãã ããð
ç§ã®ãã«ãã¹ã¯ãªããã¯ããå°ãå€ãã®ããšãè¡ã£ãŠããŸãããããã¯é åã®ããã«æ©èœããŠããããã§ãïŒ
"build": "graphql codegen && next build && npm run export",
ãã®äžãããã¯çŽ æŽãããã§ãïŒ ããã¯ãŸãã«ç§ãæ¢ããŠãããã®ã§ããð ïŒããããªãGatsbyJSãç§ã®ãæ°ã«å ¥ãã®ãã¬ãŒã ã¯ãŒã¯ã¯ããªãã®ããã«åŒ·åã«ãªããŸããïŒïŒ
ãã®ãããªåå¿æ§ã«æè¬ããŸãã
ç§ã9.1.6
ã¢ããã°ã¬ãŒãããŸããããé©ããããšã«ãããèŠãŸãã
ã¹ã¬ããã¯RFCã ãšæã£ãŠããŸãããããã§ã«å
¬éãããŠããããã§ãã
ãã ããTypescriptã¿ã€ãã¯9.1.6ã§ã¯æå¹ã«ãªã£ãŠããŸããã
ãããŒãç§ã¯ä»ããã®ããã«ãšãŠãèªå€§å®£äŒãããŠããŸãïŒ ð€£
æåŸã®è³ªåïŒ
getInitialProps
ã¯å°æ¥éæšå¥šã«ãªããŸããïŒ ãããšããããã§ãå Žåã«ãã£ãŠã¯é¢é£æ§ããããŸããïŒ äŸïŒnext export
ã¯éæšå¥šã«ãªãã getStaticProps
ãšnext build
ã®ã¿ã®ããŒãžãåªå
ããããšãã§ããŸããïŒãã®çŽ æŽãããããŒã«ãããããšãðð»
ç§ããããååŸããå ŽåãgetInitialPropsã¯å°æ¥éæšå¥šã«ãªããŸããïŒ ãããšããããã§ãå Žåã«ãã£ãŠã¯é¢é£æ§ããããŸããïŒ äŸïŒ
æåã®RFCã§è¿°ã¹ãããã«ïŒ
ãã®RFCã¯ãAPIã®è¿œå ã«ã€ããŠã®ã¿èª¬æããŠããŸãã ãã¹ãŠã®æ°æ©èœã¯å®å šãªäžäœäºææ§ãããã段éçã«æ¡çšã§ããŸãã ãã®RFCã¯éæšå¥šãå°å ¥ããŠããŸããã
ã¹ã¬ããã¯RFCã ãšæã£ãŠããŸãããããã§ã«å ¬éãããŠããããã§ãã
ããã§ã¯ãããŸãããç§ãã¡ã¯ZEITã¢ããªã±ãŒã·ã§ã³ã§ãããè©ŠããŠããŸãããå¯èŠæ§ã®è¡šé¢åã®äžéšã¯ãã§ã«çéžããŠããŸãïŒããšãã°ãããªããèŠãããŒãžããªãŒïŒã
次ã®ãšã¯ã¹ããŒãã¯ãgetStaticPropsãšæ¬¡ã®ãã«ãã®ã¿ã®ããŒãžãåªå ããŠéæšå¥šã«ããããšãã§ããŸããïŒ
æ£è§£ã§ããäžè¬çã«ã next export
ã䜿çšããªãããšã«ãªããŸãã åŸæ¹äºææ§ã®çç±ã§ä¿æãããŸãããAPIã«ãŒããäžéšã®ããŒãžã®ãµãŒããŒåŽã¬ã³ããªã³ã°ã®ãªããã€ã³ãªã©ã®ä»ã®æ©èœããµããŒãããããšã§ããšã¯ã¹ããŒãã®ãã¹ãŠã®å©ç¹ãåŸããããããäžè¬ã«ãã€ããªããã¢ããªãäœæããããšããå§ãããŸãã
ã©ãããã°ããããè©Šãããšãã§ããŸããïŒ
ãããã®ã¡ãœããã¯ãã¹ãŠãèªèãããããã«çŸåš
unstable_
ãã¬ãã£ãã¯ã¹ãå¿ èŠã ãšæããŸããäŸïŒ
unstable_getStaticProps
ãŸã 䜿çšããªãããšã匷ããå§ãããŸããããã¯å®éšçãªãã®ã§ããããªãªãŒã¹éã§äžæããå¯èœæ§ããããŸãã
ãã®ããããã®æ©èœãè©ŠããŠã¿ãŸããããããŒãžããŒã¿ãå«ãJSONãã¡ã€ã«ã¯ãå¥ã®ããŒãžããSSGããŒãžã«ã¢ã¯ã»ã¹ããåŸã«åžžã«ãã§ãããããããšãããããŸããã
JSONãã¡ã€ã«ã®ããªããŒãã®æé©åãèšç»ããŠããŸããïŒ
ããããããŠãŒã¶ãŒãããŒãžã«ç§»åããããšããŠãããšãïŒã€ãŸãããŠãŒã¶ãŒãSSGãªã³ã¯ããããŒããŠãããšãïŒã«ããªããŒããããããªã³ã¯ã³ã³ããŒãã³ãããåç
§ãããŠããä»ã®jsããŒãžãããªããŒãããã®ãšåãããã«ããªããŒãããŸãã
ã¡ãªã¿ã«ãã®ç¹åŸŽã倧奜ãïŒ
JSONãã¡ã€ã«ã®ããªããŒãã®æé©åãèšç»ããŠããŸããïŒ
ã¯ãã
䟡å€ãããã®ã¯ãåå¥ã®ãã¡ã€ã«ã§ã¯ãªãããããã®é¢æ°ã®ããªãŒãæºãããããšãã§ãããšã¯ã¹ããŒãã§ãã
ãã®æ©èœã®ã¹ããŒã¿ã¹ã¯ã©ããªã£ãŠããŸããïŒ ãã®ãããã«ãŒã¯äœã§ããïŒ
@mikestopcontinuesãã®RFCã¯çŸåšãç§ãã¡ã®ããŒã ãšããã€ãã®éžæãããããŒãããŒã«ãã£ãŠå éšã§åŸ¹åºçã«ãã¹ããããŠããŸãã äžèšã®ããã«ã éåžžã«å®éšçãªåäœãéžæã§ããŸãã ð
ãã ããAPIãç Žå£çãªæ¹æ³ã§æŽæ°ããå¯èœæ§ããããããæ¬çªã¯ãŒã¯ããŒããæ°ããã¡ãœããã«ç§»è¡ããªãã§ãã ããã
å人çã«ã¯ã8ã20KããŒãžã®éçãµã€ãã®çæã«äœ¿çšããŠããŸãïŒäžéšã®ããŒãžã§åçãªèŠæ±ãçºçããå¯èœæ§ããããŸãïŒã ããã¯éåžžã«ããŸãæ©èœããŸãïŒNowã®10Kãã¡ã€ã«ã®å¶éãé€ãïŒãæ®å¿µãªã®ã¯ãgetStaticPathsã¡ãœããããªããšããªããŒãã®ãã³ã«getStaticPropsãåŒã³åºãããããšã ãã§ãã è¯ãåäœã®1ã€ã¯ãæåã®åŒã³åºãã§jsonãã¡ã€ã«ãäœæããã次ã®åŒã³åºãã§ããã䜿çšãããããšã§ãã
ã€ã³ã¯ãªã¡ã³ã¿ã«ãã«ãã¯èšç»ãããŠããŸããïŒ ã§ã¯ãæ°ãã/å€æŽãããã³ã³ãã³ãã®ã¿ãåæ§ç¯ãããŸããïŒ
äžèšã®ããã«ã éåžžã«å®éšçãªåäœãéžæã§ããŸãã
unstable_getServerProps
ã¡ãœããããã¹ããããã®ã§ãããçŸæç¹ã§ã¯ç¡èŠãããŠããããã§ã zeit/next.js
ãªããžããªã®ã©ãã«ãèŠã€ãããŸããã ããã¯ãŸã å®è£
ãããŠããŸãããããããšãç§ã¯ãããééã£ãŠããã ãã§ããïŒ
ã€ã³ã¯ãªã¡ã³ã¿ã«ãã«ãã¯èšç»ãããŠããŸããïŒ ã§ã¯ãæ°ãã/å€æŽãããã³ã³ãã³ãã®ã¿ãåæ§ç¯ãããŸããïŒ
å®è£ ã¯ã€ã³ã¯ãªã¡ã³ã¿ã«åæ§ç¯ã念é ã«çœ®ããŠèšèšãããŸãããããŸã ãµããŒããããŠããŸããïŒãã®RFCã§ã¯ã«ããŒãããŠããŸããïŒã
ã¢ãŒããã¯ãã£ã¯æºåãã§ããŠããããããã®æ©èœãå®å®ããåŸã§ããã調æ»ããŸãã®ã§ããå®å¿ãã ããã
ãããã getStaticProps
ãããŒãžããšã«å®çŸ©ãããã¢ããªã±ãŒã·ã§ã³å
šäœã«å¯ŸããŠ1åã§ã¯ãªãçç±ã§ãã
äžå®å®ãªgetServerPropsã¡ãœããããã¹ããããã®ã§ãããçŸæç¹ã§ã¯ç¡èŠãããŠããããã§ã[...]
getServerProps
ã¯ãŸã ãã¬ãã¥ãŒã§å©çšã§ããŸãããç³ãèš³ãããŸããã
getServerProps
ã¯ãŸã ãã¬ãã¥ãŒã§å©çšã§ããŸãããç³ãèš³ãããŸããã
ãããã¢ãããããããšãã ç§ã¯ééããªããã®ã¹ã¬ãããèŠãŠããŸãããªããªãããããçå°ãããšãåäžã®é¢æ°ã®ååãå€æŽããããšã§çœ®ãæããããšãã§ããã³ãŒãã®_æ_ãããããã§ãïŒ ð
getServerProps
/ getStaticProps
ãçŸåšäœ¿çšå¯èœãã©ããã¯ã100ïŒ
確å®ã§ã¯ãããŸããã
ãã®ã¹ã¬ããã«åºã¥ãïŒããã
ããããããã ãšããã°ã next build
ãå®è¡ãããšãã«ããŸã å©çšã§ããªãã®ã«ããªãç§ã®ç«¯æ«ããããã»ã®ããããŠããã®ã ããããšæããŸãã ã¡ãã»ãŒãžãèŠããšããããã®ã¡ãœãããæ¬çªç°å¢ã«ãããšããæåã®äœæ¥äžã®æ³å®ãæ®ããããã§ãªãããšãçºèŠããã®ã«ãã°ããæéãããããŸããã çç±ã«ã€ããŠããŸãã¯ç§ã誀解ããŠããããšããããã©ããã ããæ°ã«ãªããŸãã
λ (Server) server-side renders at runtime (uses getInitialProps or getServerProps)
â (Static) automatically rendered as static HTML (uses no initial props)
â (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
ïŒæ¬¡ã®ããŒãžã§ã³9.1.6ïŒ
ããããšã
@stevenjchang pages/**/*.js
次ã®æ§æã䜿çšããŠå©çšã§ããŸãã
export function unstable_getStaticPaths() {} // return [{params: {...}}, ...]
export function unstable_getStaticProps({params: {...}) {} // return {props: {...}}
ãŸããéçºãµãŒããŒã䜿çšãããšãã¯ãŸã å°ãèãã§ããããã°ãããããšãä»ãå ããŠãããŸãã
ãã ããéçºãµãŒããŒã䜿çšããå Žåã¯ããŸã å°ãèãã§ãã
@mikestopcontinues
ããã«ã€ããŠè©³ããæããŠããã ããŸããïŒ éçºãµãŒããŒã®ãšã¯ã¹ããªãšã³ã¹ã«ã€ããŠåŠå®çãªãã£ãŒãããã¯ãå¯ããŠããã人ã¯ä»ã«ããŸããã解決ããŠããããããšæã£ãŠããŸãã
@Timerç§ã¯æ°ããAPIãæ¬åœã«å¥œãã§ãã éçºäžã®ç§ã®äž»ãªåé¡ã¯ãjsonãããŒãã®ãã³ã«åèŠæ±ãããããšã§ãã ããã«ãããã¹ãã®é床ãäœäžããŸãããå®éã«ãµã€ããé²èŠ§ãããšãã®ãŠãŒã¶ãŒãšã¯ã¹ããªãšã³ã¹ã誀ã£ãŠè¡šç€ºãããŸãã
ããã¹ãŠã®èªã¿èŸŒã¿æããšã¯ãããŒãžã®èªã¿èŸŒã¿ãæå³ããŸããïŒ ãŸãã¯åæ§ç¯ããŸããïŒ ãŸãã¯...ïŒ
@mmmeffåããã¹ã«ç§»åãããã³ã«ãjsonãåèŠæ±ãããŸãã ãããã£ãŠã2ã€ã®ããŒãžéãè¡ã£ããæ¥ãããããšãããŒã¿ãåŸ ã€ã®ã«å€ãã®æéãè²»ããããŸãã
@mikestopcontinuesããã¯æå³ãããåäœã§ããéçºã§ã¯ãææ°ã®ããŒã¿ãæãŸããå Žåãå€ãããã§ãã æ°ããåé¡ã§ããã€ãã®ããè¯ããã¥ãŒãªã¹ãã£ãã¯ã«ã€ããŠè°è«ããããšã«ãªãŒãã³ã«ãªããŸãïŒ
@timneutkensãã®RFCã¯éåžžã«ææã«èŠããŸãã ã»ãã¥ãªãã£ãšããããæ£ç¢ºã«ã©ã®ããã«æ©èœãããã«ã€ããŠãããã€ã質å/æžå¿µããããŸãã
SSRãšSSGã®äž¡æ¹ã«äŸåããäžè¬çãªããžãã¹ã±ãŒã¹ãèããŠã¿ãŸãããã
ãŠã§ããµã€ãïŒå¥åãã¢ããªãïŒã«ããã€ãã®æ
å ±ã衚瀺ããããšæããŸãã
ãããã®æ
å ±ã¯ãGraphQLAPIãä»ããŠã¢ã¯ã»ã¹ã§ããBDDã«æ ŒçŽãããŸãã
ãããã®æ
å ±ã®äžéšã¯å
¬éãããŠãããäžéšã¯éå
¬éã§ãïŒã€ãŸãããŠãŒã¶ãŒã®é»åã¡ãŒã«/ãã¹ã¯ãŒãïŒã
ã¢ããªã¯2ã€ã®æ®µéã䜿çšããŸãã
ãã®ã·ããªãªã§ã¯ãSSRãšSSGã®äž¡æ¹ã䜿çšããŸãã
ãã®ã·ããªãªã¯ååã«äžè¬çã§ãããïŒIMHOïŒSSG䜿çšã®äž»èŠãªãŠãŒã¹ã±ãŒã¹ã®1ã€ã§ããå¿ èŠããããŸãã
æ¬çªã¢ããªã¯ãã¹ããŒãžã³ã°ã¢ããªã®ã¹ãããã·ã§ããã«ãããŸããã
ããã¯ãã€ãªãªãŒã¹ããäºå®ã§ããïŒ ã¡ãžã£ãŒã¢ããããŒãïŒv10ïŒã«ãªãã®ã§ããããããããšãäžäœäºææ§ã®ããã¢ããããŒãã«ãªãã®ã§ããããã
ããã
ã«ã¹ã¿ã ãµãŒããŒã§ãã®ãœãªã¥ãŒã·ã§ã³ãè©Šããæ©èœããã人ã¯ããŸããïŒ
äŸïŒ
// server.js
const express = require('express');
const next = require('next');
const port = parseInt(process.env.PORT, 10) || 3000;
const dev = process.env.NODE_ENV !== 'production';
const app = next({ dev });
const handle = app.getRequestHandler();
app.prepare().then(() => {
const server = express();
server.get('/blog/:id', (req, res) => {
console.log('My params needed be passed to page:', req.params);
return app.render(req, res, '/blogDetail', { id: req.params.id });
});
server.listen(port, err => {
if (err) throw err;
console.log(`> Ready on http://localhost:${port}`);
});
});
// blogDetail.js
export async function unstable_getStaticProps(props) {
console.log('What is passed', props);
return {};
}
const BlogPostPage = ({ post }) => {
return <div>Hey</div>;
}
export default BlogPostPage;
# Terminal output
My params needed be passed to page: { id: 'test' }
What is passed { params: undefined }
getStaticProps
ã«ã¯ãšãªæååãå«ããããšãã§ããªãã®ã¯ãªãã§ããïŒ çŸåšãåã¬ã³ããªã³ã°ããã«ã¯ãšãªãã©ã¡ãŒã¿ãååŸããããã ãã«SSRãå®è¡ããå¿
èŠãããããŒãžããããŸãã ã¯ãšãªã¯æåã¯ç©ºã®ãªããžã§ã¯ãã§ããããã useRouter
ããã¯ã䜿çšãããšãè€æ°ã®åã¬ã³ããªã³ã°ãçºçããŸãã ããã¯ã³ã³ããŒãžã§ã³ãã©ããã³ã°ã«äœ¿çšãããããŒãžã§ãããããæããã«ãåå¿è
ã§ã¯ãããŸããã
@pjaws RFCã¯ã getStaticProps
ãéççæçšã§ãããšå
·äœçã«è¿°ã¹ãŠããŸãã éçHTMLã¯ã¯ãšãªæååãåãåãããšãã§ããŸããã
ã§ã¯ããªãåçURLãã©ã¡ãŒã¿ãŒãåãåãããšãã§ããã®ã§ããããã ããã¯ã©ãéãã®ã§ããïŒ
1:30ãã£ã Neutkensã§ç«ã2020幎1æ14æ¥ã«ã¯[email protected]
æžããŸããïŒ
@pjawshttps ïŒ//github.com/pjawså ·äœçã«èšåãããŠããRFC
getStaticPropsã¯éççæçšã§ãã éçHTMLã¯åä¿¡ã§ããŸãã
ã¯ãšãªæååãâ
ããªããèšåãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AMVRRIQCKDJNF4MPWSLYNV3Q5WA2NA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5
ãŸãã¯è³Œèªã解é€ãã
https://github.com/notifications/unsubscribe-auth/AMVRRIRJXLYC4MC4U7DH7NDQ5WA2NANCNFSM4JRPBELQ
ã
getStaticPaths
ã§ã¯ããã«ãæã«ã¬ã³ããªã³ã°ãããããŒãžãè¿ãå¿
èŠãããããã§ãã
ãããã®å€æŽã¯ããã€ãã®ããã«éåžžã«ææã§çŽ æŽãããä»äºã«èŠããŸãïŒ ð
ããŒãžéã§å
±æãããããŒã¿ã®ããŒãºãæºããããã«ã _app.js
ã«getInitialProps
ãå«ãããŠãŒã¹ã±ãŒã¹ã«ã€ããŠçåã«æããŸãïŒã³ã³ããã¹ããããã€ããŒã®èšå®ãªã©ïŒã getStaticProps
ãåãããã«äœ¿çšããããšã¯äžå¯èœã§ããããšãæ£ããç解ããŠããŸããïŒ åã
ã®ããŒãžã§ã®ã¿å®çŸ©ããããšã¯å¯èœã§ããïŒ
_app.jsã«getInitialPropsãé 眮ããŠãããŒãžéã§å ±æãããããŒã¿ã®ããŒãºãæºããïŒã³ã³ããã¹ããããã€ããŒã®èšå®ãªã©ïŒãŠãŒã¹ã±ãŒã¹ã«ã€ããŠçåã«æããŸãã getStaticPropsãåãããã«äœ¿çšããããšã¯äžå¯èœã§ããããšãæ£ããç解ããŠããŸããïŒ åã ã®ããŒãžã§ã®ã¿å®çŸ©ããããšã¯å¯èœã§ããïŒ
æ£è§£ã§ããæåã¯åã ã®ããŒãžå°çšã§ãã åŸã§åèãããããããŸããã _appã®getInitialPropsã¯ãéçHTMLã«ãšã¯ã¹ããŒããããšãã«åŒãç¶ãåŒã³åºããããããgetStaticPropsã«æ®µéçã«ç§»åã§ããŸãã
ããã«ã¡ã¯ã¿ããªã1ã€ã®é¢é£ãã質å-è³ç£ã¯ã©ã®ããã«æ±ãããŸããïŒ ãããã¬ã¹CMSïŒwordpressãgraphcmsãªã©ïŒã䜿çšããŠããå Žåãéçhtmlã§ã¢ã»ããã®URLã䜿çšãããŠããããšãããããŸããã
ããã«ã¯2ã€ã®èšå®ããããŸã-ã¢ã»ãããªã³ã¯ããã®ããã«äœ¿çšããããšã§ãã
ããããããå¯èœæ§ãé«ãã®ã¯ãã¢ã»ãããããŠã³ããŒãããhtmlããã«ãããŠïŒããŒã«ã«ã«ãªã³ã¯ããïŒãCDNãåé¢ã«ã¬ã€ã€ãŒåããããšã§ãã ããã¯ã¯ããã«åãå
¥ããããæ¹æ³ã§ãã
ããã¯ãNetlifyã®ãããªå±éã·ã¹ãã ã®äœ¿çšãšãéåžžã«ããçµã³ã€ããŠããŸããNetlifyã¯ãDatoCMSãGraphcmsã®ãããªãã®ãããã¯ããã«é©åãªã°ããŒãã«ã«å©çšå¯èœãªã€ã³ãã©ã¹ãã©ã¯ãã£ãåããŠããŸãã ãããã£ãŠãå±éãšããŠNetlifyã䜿çšããŠããå Žåã¯ããã¹ãŠãNetlifyãã¡ã€ã³ããæäŸãããã®éæ³ãåãããããšæã
@sandys https://github.com/zeit/next.js/issues/9054#issuecomment -570427085ã§æ£ããç解ããŠããå Žåã¯ãã¢ã»ãããããŠã³ããŒããã .next/static
äžã«ä¿åããŠããªã³ã¯ãäœæããŸãã getStaticProps
èªåèªèº«ã
éçAPIã«ãŒãã䜿çšãããšããã¢ã€ãã¢ããããŸãããããã䜿çšããŠãã©ãŠã¶ãŒã®ãã£ãã·ã¥åäœãã©ã®ããã«å¶åŸ¡ãããã¯æ£ç¢ºã«ã¯ããããŸããã
@Janpotãªã³ã¯ããŠãããŠããããšãã ããã«ããã³ã¡ã³ãã¯ããã®ãããªãã®ã¯èªåã®ãã®ã§ãªããã°ãªããªãããšã瀺ããŠããããã§ãã
ãã®çµã¿èŸŒã¿ã«ç§ã®ãªã¯ãšã¹ããè¿œå ããŠãã ããã ããããïŒ9054ã®æ¹ãäžè¬çã§ãããSSGã®èŠ³ç¹ããèãããšãããã¯éåžžã«éèŠã§ãã
èšåããã®ãå¿ããŸããããSSGã«ã¯ã¢ã»ããããã·ã¥ãäžå¯æ¬ ã§ãã
@homoky ããããæ©èœãããããšãã§ããŸãã
@homoky ããããæ©èœãããããšãã§ããŸãã
ããã¯äžå¯èœã§ãããèšç»ããããŠããŸããïŒïŒ10071
ð¢
@sandysã¯ã httpsïŒ//github.com/zeit/next.js/issues/9081ã䜿çšããŠ/images
ããCMSã«æžãæããè¿œå ãããšãå®éã®ãœãªã¥ãŒã·ã§ã³ã¯ã¯ããã«ç°¡åã«ãªããŸãã ZEITãªã©
@timneutkensè¿ä¿¡ããããšã
ããªããäœãæå³ããã®ãå®å
šã«ã¯ããããŸããã ãããã£ãŠãnetlifyã䜿çšããŸã-CMS URLããã®ãŸãŸä¿æãããã®äžã«CDNã®ã¬ã€ã€ãŒãåé¢ã«é
眮ããããšãææ¡ããŠããŸããïŒ
netlifyïŒäœ¿çšããäºå®ã®ã¯ã©ãŠãããã³ãïŒãããããã¹ãŠã®ãµãŒãã¹ãšã·ãŒã ã¬ã¹ã«é£æºã§ãããã©ããã¯ããããããŸããã
ã€ã¡ãŒãžãããŠã³ããŒããããŠå±éã®äžéšã«ãªããšããã®åé¡å šäœãå€§å¹ ã«åçŽåãããŸãã ããŒã¹URLãããã£ãã·ã¥ããããã«CDNãèšå®ããŠããããïŒç§ã®å Žåã¯s3ããæäŸãããŸãïŒã
ããªãã®ãœãªã¥ãŒã·ã§ã³ãZeitNOWã䜿çšããŠç§ã«åºã¥ããŠãããã©ããå®å šã«ã¯ããããŸãã
ã€ã¡ãŒãžãããŠã³ããŒããããŠå±éã®äžéšã«ãªããšããã®åé¡å šäœãå€§å¹ ã«åçŽåãããŸãã ããŒã¹URLãããã£ãã·ã¥ããããã«CDNãèšå®ããŠããããïŒç§ã®å Žåã¯s3ããæäŸãããŸãïŒã
ããã«ãããå®éã«ã¯ãã«ãããã»ã¹ãã¯ããã«è€éã«ãªãã10åé ããªããŸããã決ããŠåçŽã§ã¯ãããŸããã
ããªãã®ãœãªã¥ãŒã·ã§ã³ãZeitNOWã䜿çšããŠç§ã«åºã¥ããŠãããã©ããå®å šã«ã¯ããããŸãã
äžçäžã®ãã¹ãŠã®ãããã·ã§åäœããŸãã ã¯ã©ãŠãããã³ããå«ã¿ãŸãã
@timneutkensã¯ãå®éã«ã¯ãã«ãããã»ã¹æéã«äŸåã
ç§ã¯ç¢ºãã«ããªããçã®ããã«ããããªã³ã«ããããšã䞻匵ããŠããŸããã å€ãã®äººãCMSã«ãã£ãŒããªã³ã¯ããããšãåãã§ããŸãã ããããç§ãã¡ã¯ãã©ãã£ãã¯ã®å€ããµã€ããéå¶ããŠãããããã¯ééããªãç§ãã¡ã®ãããªãµã€ããå¿ èŠãšããŠãããã®ã§ãã
ãŸããç§ãèš±ããŠãã ããããããç§ã¯ããªãã®è§£æ±ºçãç解ããŸããã§ããã ãããã©ã®ããã«æ§æããå¿ èŠããããŸããïŒ CMSã䜿çšããURLãå¶åŸ¡ã§ããŸããã ããšãã°ãDatocmsã¯www.datocms-assets.com/ãããµãŒãã¹ãéå§ããŸãã ïŒ9081ã®ãœãªã¥ãŒã·ã§ã³ãã©ã®ããã«äœ¿çšããŸããïŒ
å®éã«ã¯ããã«ãããã»ã¹ã®æéã«ã¯äŸåããŸããã æéãããã£ãŠãæ§ããŸãã
ããã¯ã¢ããªã±ãŒã·ã§ã³ã«åœãŠã¯ãŸããããããŸããããã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯åœãŠã¯ãŸããŸããã
ãã ããå€ãã®çç±ïŒæ¢ç¥ã®ããŒã¹URLããæäŸããããã¹ãŠã®ã¢ã»ãããå«ãïŒã®ãããããããã«ãã§ãã€ã¯åŠçããããšã匷ããå§ãããŸãã
å®éã«ã¯ãèšãããŠããå¿
èŠã¯ãããŸãããããšãã°ã www.datocms-asset.com/*
ãªã©ã®ããã«/images/*
ãcmsurlã«ãããã·ãããªã©ã€ãã䜿çšã§ããŸãã 次ã«ã /images
ã䜿çšããŠãã¹ãŠã®ç»åããªã³ã¯ããŸãã
ããã¯è©±é¡ããå€ãå§ããŠããããšã«æ³šæããŠãã ããã
@sandysã¯ãå®éã«ã¯ãïŒ9081ã䜿çšããŠ/ imagesããCMSã«æžãæããè¿œå ãããšããœãªã¥ãŒã·ã§ã³ãã¯ããã«ç°¡åã«ãªããŸãã ZEITãªã©
@timneutkensç§ã®ããã«ç©äºãæ確ã«ããããã ãã«ã çæ³çãªç¶æ³ã§ã¯ãç»åãããã·ã¥ããŠãã©ãŠã¶ã®äžæã®URLã§æ°žä¹ ã«ãã£ãã·ã¥ããã³ã³ãã³ãäœæè ã¯CMSã§åãååã§ãã€ã§ããã¡ã€ã«ãæŽæ°ã§ããŸãã ã€ãŸããã»ããã¢ããã§ã¯ãCMSã次ã®è²¬ä»»ãè² ãå¿ èŠãããããšãææ¡ããŸãã
getStaticProps
ã§ããŠã³ããŒãããŠãç»åã®URLãCMSäžã®äžå€ã®å¯Ÿå¿ãããã®ã«åãããã§ããŸããããã¯äžå¯èœã§ã¯ãªããšæããŸãã ãããææ¡ãããèšå®ã§ããããšã確èªãããã ãã§ãã
@Janpot CMSãããã€ããŒã¯ãç»åãªã©ã«äžæã®URLãæå®ããããšã§ãããããã§ã«åŠçããŠããŸãã
ããã¯ã¢ããªã±ãŒã·ã§ã³ã«åœãŠã¯ãŸããããããŸããããã»ãšãã©ã®ã¢ããªã±ãŒã·ã§ã³ã«ã¯åœãŠã¯ãŸããŸããã
ç¹°ãè¿ããŸãããããã§ã¯ç§ã ãã§ã¯ãããŸããã åæ§ã®ãªã¯ãšã¹ãããããããããŸãã ãã²ãæ€èšãã ããã
gatsbyåŽã§ã-https ïŒ//github.com/gatsbyjs/gatsby/issues/14076
https://github.com/njosefbeck/gatsby-source-stripe/#downloading -files
@sandysããã¯
ããããç§ãã¡ã®å¿ã®ãã¹ãŠã«ãããŠãããã¯SSGãšå¯æ¥ã«é¢é£ããŠããããšãè¿°ã¹ããã£ãã ãã§ãã çæ³çãªã±ãŒã¹ã¯ãSSGãšã¯ã¹ããŒãã³ãã³ãããããè¡ãããšã§ãã éåžžãããã¯ä»ã®å Žåã«ã¯å¿
èŠãããŸããã
æè¯ã®ã±ãŒã¹ã¯ãããã次ã®ãšã¯ã¹ããŒãæã«ãªãã·ã§ã³æ©èœã«ãªãããšã§ãã
ããããããªããæãããã«-ããªãã®æ±ºå®ãå°éããŠãã ããã
ããããããã¯next export
ãçŸåšãè¡ã£ãŠããªãããšã§ãã ãããã£ãŠããããå®å
šã«æ°ãããã®ã§ããããã®RFCãšã¯ç¡é¢ä¿ã§ããçç±ã
ãŸãã getServerProps
ããªã³ããã³ãã¬ã³ããªã³ã°ã§ã¯äœ¿çšã§ããŸããã
@Janpot CMSãããã€ããŒã¯ãç»åãªã©ã«äžæã®URLãæå®ããããšã§ãããããã§ã«åŠçããŠããŸãã
ðã¯ããããã¯çã«ããªã£ãŠããŸãã ãã ãããããžã§ã¯ãã§ç»åã䜿çšããããããæé©åããŠãã£ãã·ã¥ããå Žåã¯ã次ã®2ã€ã®éžæè¢ããããŸãã
ç·šéïŒ
ãããŠãç§ãæ£ããç解ããŠããã°ã file-loader
ã¯ãã§ã«CSSã«å«ãŸããŠããŸãã JSã§ãæå¹ã«ããã®ã§ã¯ãªãã§ããïŒ
@Janpot Sandeepãèšåããç¹å®ã®ãã€ã³ãã¯ãURLã¯ãããžã§ã¯ãèªäœã§ã¯ãªããå€éšãœãŒã¹ãã
ZEIT Nowã«ãããã€ããããµã€ãã®å Žåãæ°ããéçAPIã䜿çšããŠåçURLãæã€ããŒãžãããå Žåã unstable_getStaticPaths
ã䜿çšããŠéçã«çæãããŠããªãããŒãžã®å Žåãé¢æ°unstable_getStaticProps
ã¯ã404ãè¿ãã®ã§ã¯ãªããå®è¡æã«ãµãŒããŒäžã§å®è¡ãããŸãã
ããšãã°ã /blog/[slug].js
ããŒãžãããããã®getStaticPaths
ã¯é
åãè¿ããŸãã
[{ params: { slug: 'hello' } }]
ç§ã®getStaticProps
ã¯ãã¹ã©ãã°ã«åºã¥ããŠãã¡ã€ã«ãèªã¿åãããžãã¯ããããŸãã /blog/hello
ã«ã¢ã¯ã»ã¹ãããšãããŒãžã¯æåŸ
ã©ããã«äºåã¬ã³ããªã³ã°ãããŸããã /blog/doesnt-exist
ãããªç¡å¹ãªããŒãžã«ã¢ã¯ã»ã¹ãããšãå®è¡æã«getStaticProps
ãå®è¡ããããšã©ãŒ500ã衚瀺ãããŸãããŸãã¯ããšã©ãŒåŠçãè¿œå ãããšã getStaticPaths
ããã®åºåã«ãªã¹ããããŠããªãã«ããããããã404ã§ã¯ãªãããŒãžãã¬ã³ããªã³ã°ãããŸãã
ãã®ããžãã¯ã¯æå³çãªãã®ã§ããïŒ
ããã¯å€§ããªæ¹åã§ãã ãããè¡ãããã«ããã«ãåã®ã¹ã¯ãªãããäœæããããšããŠããŸããã
Next 9.2ã§ãµã€ãã®1ã€ãunstable_getStaticPaths
ãšunstable_getStaticProps
ã«ç§»åããããšããã¹ããããšãããããŸããããŸããã
exportPathMap
ãšæ¯èŒããŠ1ã€ã®ååž°ããããŸãã exportPathMap
ã䜿çšããŠãã¹ãæ§ç¯ããå Žåã次ã®ããã«æå®ã§ããŸãã
{
"/path/to/page": {page: "/index", query: { pageId: 123 } }
}
éçãã«ãããã«ããããŸã
/path
/to
/page
index.html
ãã³ãã¬ãŒã[slug].jsx
unstable_getStaticPaths
ããåçã®ãã®ãè¿ããšã
[{ slug: '/path/to/page' }]
次ã®9.2ã¯ããã¹ãããããã£ã¬ã¯ããªã®ä»£ããã« 'ïŒ 2FpathïŒ 2FtoïŒ 2Fpage`ãçæããŸãã
/%2Fpath%2Fto%2F
index.html
ãã£ã¬ã¯ããªãæ§ç¯ããïŒæ¢åã®exportPathMapã®åäœãšäžèŽããïŒããšã¯ãããŒãžãæ§ç¯ããæ¹æ³ã«ãšã£ãŠéèŠã§ãã åäžã®ãã³ãã¬ãŒããã¡ã€ã«ã䜿çšããŸãããå ¬éããããã¹ã¯ä»»æã«ãã¹ãã§ããŸãã
@dpfavandãã®å Žåã¯ããã£ãããªãŒã«ã«ãŒãã䜿çšããå¿ èŠããããŸãïŒ https ïŒ //nextjs.org/blog/next-9-2#catch -all-dynamic-routes
æœåšçã«ããªããã¹ã©ãã·ã¥ãå«ããã¹ãè¿ãããã«ããããšãããšãç§ãã¡ã¯èŠåããããšãã§ããŸããã䜿çšããŠãããšãã®åäœã¯æ£ããã§ã[slug].js
ããªãã®ã±ãŒã¹ã§ã¯ãããªãããããã [...slug].js
ã
ããã¯ãã€çéžãããšäºæ³ãããŸããïŒ 9.2ã®ãããã«å«ãŸããã®ã§ããããããããšãç¬èªã®ãã€ããŒããŒãžã§ã³ã«ãªãã®ã§ããããã
ãã®æ©èœã«é¢ãããã¹ãŠã®è奮ã«å¿ããæè¬ããŸãã ä»ã®å Žæã§è¿°ã¹ãããã«ãé©åãªéçºè ãšã¯ã¹ããªãšã³ã¹ãå¶çŽãããã³å°æ¥ã®èšŒæ æ§ã確ä¿ãããã®ã§ãéåžžãæ©èœã®ã¿ã€ã ã©ã€ã³ãå ±æããŸããã
ããã¯æ°æ©èœãªã®ã§ããã€ããŒã«ãªããŸãã
ãããæ®éã¯ç解ã§ããŸããã9.1.7ã®ããã°ãå°è±¡çã§ãã
ããã¯ãã§ã«éçã«åºãŠããŸããã
17:05ãã£ã Neutkensã§éã2020幎1æ17æ¥ã«ã¯[email protected]
æžããŸããïŒ
ãã®æ©èœã«é¢ãããã¹ãŠã®è奮ã«å¿ããæè¬ããŸãã è¿°ã¹ãããã«
ä»ã®å Žæã§ã¯ãéåžžãæ©èœã®ã¿ã€ã ã©ã€ã³ãå ±æããŸããã
圌ããé©åãªéçºè ã®çµéšãå¶çŽããããŠå°æ¥ãæã£ãŠããããšã確èªããŠãã ãã
蚌æ æ§ãâ
ããªããã³ã¡ã³ãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=ADKINGF724256WCEFHBFIH3Q6ITRXA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5WW2Z
ãŸãã¯è³Œèªã解é€ãã
https://github.com/notifications/unsubscribe-auth/ADKINGBVCG6MFMOG5U2FGMDQ6ITRXANCNFSM4JRPBELQ
ã>>
ã©ã·ã¿ãŒã°ã¬ãã°
[email protected] [email protected]
ã»ã«ïŒ832ïŒ495-9903
getStaticProps
ãããªãã®ã¯ãããŸãããããŒãžããšã§ã¯ãªãã¢ããªå
šäœã§1åã ãå®è¡ãããŸããïŒ
ç§ã®ãŠãŒã¹ã±ãŒã¹ã¯ãè€æ°ã®ããŒãžã§äœ¿çšãããReactã³ã³ããã¹ãïŒ PricingPlansContext
ïŒãããããã«ãæã«ããŒã¿ïŒäŸ¡æ Œãã©ã³ïŒãå€éšãµãŒããŒãã1åã ãååŸããããšã§ãïŒ next export
ïŒã å®è¡æã«ããã¹ãŠã®ããŒãžããgetStaticProps
ã«è¿œå ããå¿
èŠããªãããšã¯ãããŸããã
ç·šéïŒäžèšã®é¢é£ã³ã¡ã³ããèŠã€ããŸããïŒ https ïŒ//github.com/zeit/next.js/issues/9524#issuecomment-574179540ã ããŸãããã°ãããã¯èæ ®ãããŸãã
ç§ã¯ãã®ããã«babel
plugin-preval`ã䜿çšããŸããã人ã
ã
next.config.jsãå«ãexportPathMaïŒïŒå
ã®jsonãã¡ã€ã«ãã€ã³ããŒãããŸãã
圌ãã®ã³ãŒãå
ã
ä»ã®ãšãããnpmã¹ã¯ãªããã䜿çšããŠjsonãã¡ã€ã«ãäœæããããšã«ãªããŸããããexportPathMapãææ¡ããŠãããŠããããšãããããããããããè¯ãå Žæã§ãã
@dpfavandãã®å Žåã¯ããã£ãããªãŒã«ã«ãŒãã䜿çšããå¿ èŠããããŸãïŒ https ïŒ //nextjs.org/blog/next-9-2#catch -all-dynamic-routes
æœåšçã«ããªããã¹ã©ãã·ã¥ãå«ããã¹ãè¿ãããã«ããããšãããšãç§ãã¡ã¯èŠåããããšãã§ããŸããã䜿çšããŠãããšãã®åäœã¯æ£ããã§ã
[slug].js
ããªãã®ã±ãŒã¹ã§ã¯ãããªãããããã[...slug].js
ã
@timneutkensãã©ããŒã¢ããã«æè¬ããŸãã ç§ã¯2ã€ã®æ¹æ³ãè©ŠããŸãããæåããŸããã§ããã æååãšããŠã¹ã©ã°å€ãæå®ããå Žåã¯ãåºæ¬çã«getStaticPaths
ããããã«æž¡ãããŠããŸããgetStaticProps
ãã¹ãŠã§ã ã¹ã©ãã°å€ãé
åãšããŠè¿ãå Žåãå€ã¯æååã§ãªããã°ãªããªãããããã«ãã¯å€±æããŸãã
ã±ãŒã¹1ããã¡ã€ã«pages/[...slug].jsx
æ³å®ããæååãšããŠã¹ã©ãã°ïŒ
export async function unstable_getStaticPaths() {
return [{ params: { slug: 'en/about' } }];
}
export async function unstable_getStaticProps({ params }) {
console.log('params', params);
return { slug: params.slug };
}
äžèšã®å Žåã params
getStaticProps
ã¯ç©ºã®ãªããžã§ã¯ãã§ããã slug
ããŒã¯ãããŸããã
ã±ãŒã¹2ã pages/[...slug].jsx
ãé
åãšããŠã®ã¹ã©ãã°ã
export async function unstable_getStaticPaths() {
const allPaths = Object.keys(pathMap).map(slug => ({ params: { slug } }));
return [{ params: { slug: ['en', 'about'] } }];
}
export async function unstable_getStaticProps({ params }) {
console.log('params', params);
return { slug: params.slug };
}
ã±ãŒã¹2ã®å Žåããã«ãã¯æ¬¡ã®ããã«å€±æããŸãã
> Build error occurred
{ Error: A required parameter (slug) was not provided as a string.
at _validParamKeys.forEach.validParamKey (/project/node_modules/next/dist/build/utils.js:21:569)
at Array.forEach (<anonymous>)
at toPrerender.forEach.entry (/project/node_modules/next/dist/build/utils.js:21:495)
at Array.forEach (<anonymous>)
at Object.isPageStatic (/project/node_modules/next/dist/build/utils.js:17:122)
at process._tickCallback (internal/process/next_tick.js:68:7) type: 'Error' }
äžèšã®getStaticPaths
äŸã«ã®ã¿ãã¹ãã©ã¡ãŒã¿ã衚瀺ãããŸãã ã¯ãšãªãã©ã¡ãŒã¿ãå«ãSSGãã¹ã䜿çšããããšã¯å¯èœã§ããïŒ äŸãã°ïŒ
/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black
ç§ã¯ç¹ã«eã³ããŒã¹ãµã€ãã®èŠ³ç¹ããèããŠããŸããããã§ã¯ãURLã®pathname
ã§è£œåæ€çŽ¢ã®ãã¹ãŠã®åŽé¢ãã«ããŒããã®ã¯é£ããã§ãããã
æè¿ããã«ã¡ãã»ãŒãžãæçš¿ããŸããããè¿ä¿¡ããããŸãã-åºæ¬çã«ããµã€ããZEIT Nowã«ãããã€ããããšã getStaticProps
ã¯getServerProps
ããã«åäœããŸãïŒã€ãŸãã getStaticPaths
ãç¡èŠããŠãªã¯ãšã¹ããåŠçããŸãïŒåçã«ïŒ-ããã¯ãã°ã ãšæããŸããïŒ
@dpfavandç§ãæ£ç¢ºãªããšãçµéšããŠããŸãïŒ CMSã®ããŒãžã«åºã¥ãåçããŒãžã«ãŒãã£ã³ã°ã䜿çšããŠ
@timneutkensãã©ããŒã¢ããã«æè¬ããŸãã ç§ã¯2ã€ã®æ¹æ³ãè©ŠããŸãããæåããŸããã§ããã æååãšããŠã¹ã©ã°å€ãæå®ããå Žåã¯ãåºæ¬çã«
getStaticPaths
ããããã«æž¡ãããŠããŸããgetStaticProps
ãã¹ãŠã§ãã±ãŒã¹1ããã¡ã€ã«
pages/[...slug].jsx
æ³å®ããæååãšããŠã¹ã©ãã°ïŒexport async function unstable_getStaticPaths() { return [{ params: { slug: 'en/about' } }]; } export async function unstable_getStaticProps({ params }) { console.log('params', params); return { slug: params.slug }; }
äžèšã®å Žåã
params
getStaticProps
ã¯ç©ºã®ãªããžã§ã¯ãã§ãããslug
ããŒã¯ãããŸããã
ãšããã§ãå°ããªäžçïŒ fastr_confã§ã話ãããã ãããããšãããããŸãã
ããã«ã¡ã¯@timneutkens ã
next.jsãéçãµã€ããžã§ãã¬ãŒã¿ãŒã®ããã«åäœããããšããã¢ã€ãã¢ã«éåžžã«è奮ããŠããŸãã
倧éã®ããŒã¿ãäžåºŠèŠæ±ãããåŸãå¥ã®ããŒãžãçæããããã«äœ¿çšãããå Žåã«ã getStaticProps
ã¡ãœãããšgetStaticPaths
ã¡ãœãããã©ã®ããã«äœ¿çšã§ããããå°ããããšæããŸãã
ããšãã°ã䜿çšå¯èœãªãã¹ãŠã®ãªããžã§ã¯ãããã§ããããã¡ãœãããæã€APIããŒã¹ã®CMSã®JavaScriptSDKã¯ã©ã€ã¢ã³ãã䜿çšããŠããŸãã ãããã®ãªããžã§ã¯ãã®äžéšã¯ãµã€ãããŒãžãè¡šããŸãã
const entries = await cmsSdkCient.getEntries();
ãããŸã§ã exportPathMap
ã¡ãœããã䜿çšããŠãCMSãããã¹ãŠã®ãšã³ããªãäžåºŠã«ãã§ãããããããã®ããŒãžã®ãã¹ãšãã®ããŒã¿ã®éã®ããããçæããŠããŸããã exportPathMap
é¢æ°ã¯2ã€ã®ããšãè¡ããŸãã
getInitialProps
ã«ãã£ãŠæ¶è²»ãããssr: true
ãæäŸããŸãssr: false
init-props.json
䜿çšããŠããã¹ãŠã®ããŒãžã®ãã¹ã«äžèŽãããã©ã«ããŒã«é
眮ãããgetInitialProps
ãåŒã³åºããããšãäžèŽããããŒãžã®init-props.json
ããå¿
èŠãªããŒã¿ãèªã¿èŸŒãŸããŸããnext.config.jsã¯
exportPathMap
module.exports = {
exportTrailingSlash: true,
exportPathMap: (defaultPathMap, { outDir }) => {
// load data from CMS
const objects = await cmsSdkCient.getEntries();
// create map between page paths and page data
return objects.reduce((accum, object) => {
// if the object does not have a slug, it is not a page
if (!object.slug) return accum;
const pagePath = '/' + object.slug;
const ssrQueryData = Object.assign({ ssr: true }, object);
const clientQueryData = Object.assign({ ssr: false }, object);
// generate the map for export phase with {ssr: true}
accum[pagePath] = {
// using additional fields from the page object,
// the pageFromPagePath() computes which page file should
// be used to render the page object
page: pageFromPagePath(object),
query: ssrQueryData
};
// write json files that will be loaded by client
if (outDir) {
const jsonFilePath = path.join(outDir, _.trim(pagePath, '/'), 'init-props.json');
fse.outputFileSync(jsonFilePath, JSON.stringify(clientQueryData));
}
return accum;
}, {});
}
}
getInitialProps
ã䜿çšããpages / my_page.js
Index.getInitialProps = async (context) => {
const ssr = _.get(context, 'query.ssr', false);
if (ssr) {
// we are on server, return the data
return _.get(context, 'query', {});
} else {
// we are on client side, request the data through /init-props.json endpoint
const url = context.asPath + '/init-props.json';
return fetch(url).then(response => {
return response.json();
});
}
};
getStaticProps
getStaticPaths
ã¡ãœãããš
// pages/my_page.js
export async function getStaticProps(context) {
const objects = await cmsSdkCient.getEntries();
const props = _.find(object, { type: 'my_page' })
return { props };
}
// pages/blog/[slug].js
export async function getStaticProps(context) {
const objects = await cmsSdkCient.getEntries();
const props = _.find(object, { type: 'post', slug: context.params.slug })
return { props };
}
export async function getStaticPaths() {
const objects = await cmsSdkCient.getEntries();
return objects
.filter(object => object.type === 'post')
.map(object => ({ params: { slug: object.slug } }))
}
getStaticProps
ãŸãã¯getStaticPaths
ãåŒã³åºããããã³ã«ãšã³ããªããã§ããããã®ã§ã¯ãªããã¯ãŒã¯ãããŒãæé©åããŠãã¹ãŠã®ãšã³ããªãäžåºŠã«ååŸããã«ã¯ã©ãããã°ããã®ã§ããããã
å¥ã®è³ªåã¯ãå¿ ããããã®åé¡ã«é¢é£ããŠãããšã¯éããŸããããç§ãã¡ã¯SSGãšãªã¢ãŒãããŒã¿ãœãŒã¹ã®äžçã«ããã®ã§ãå°ãã䟡å€ããããŸãã next.jsãéçºã¢ãŒãã§å®è¡ãããŠãããšä»®å®ãããšããªã¢ãŒãããŒã¿ãåãã§ããããŠãµã€ããåæ§ç¯ããããã«ããããã®ã¡ãœãããåå®è¡ããããã«next.jsã«éç¥ããã«ã¯ã©ãããã°ããã§ããã
@smnhããã¯ãåãªãJavaScriptãã§ããããããšã³ããªã1åãã§ããããŠãçµæãããŒã¿ãã§ããã¡ãœããã«ãã£ãã·ã¥ã§ããŸãã ä»ã®ããŒãžã®getStatic *ã¡ãœããã§å床åŒã³åºãããå Žåããããã¯ãŒã¯ãå床ãããããããšã¯ãããŸããã
2çªç®ã®è³ªåã«ã€ããŠã¯ãèªåçã«è¡ãããŸãã next dev
ãå®è¡ããã°ãæºåã¯å®äºã§ãã
äžèšã®
getStaticPaths
äŸã«ã®ã¿ãã¹ãã©ã¡ãŒã¿ã衚瀺ãããŸãã ã¯ãšãªãã©ã¡ãŒã¿ãå«ãSSGãã¹ã䜿çšããããšã¯å¯èœã§ããïŒ äŸãã°ïŒ/store/widgets/circles-n-squares?sort=price&minWeight=2&color=black
ç§ã¯ç¹ã«eã³ããŒã¹ãµã€ãã®èŠ³ç¹ããèããŠããŸããããã§ã¯ãURLã®
pathname
ã§è£œåæ€çŽ¢ã®ãã¹ãŠã®åŽé¢ãã«ããŒããã®ã¯é£ããã§ãããã
ããã¯ssgã®ã³ã³ããã¹ãã§ã¯æå³ããªããšæããŸãã SSGã¯ããã¹ãŠã®ãšã³ããªã«å¯ŸããŠãã¡ã€ã«ãåºåããŸããã¯ãšãªãã©ã¡ãŒã¿ã¯ãã¡ã€ã«åã®äžéšã§ã¯ãªãããããªã¯ãšã¹ããå®éã®ãã¡ã€ã«ã«æžãæããã«ã¯ãµãŒããŒã¬ã€ã€ãŒãå¿ èŠã§ãã ïŒäžèšã®äŸã§ã¯éçãã¡ã€ã«åã¯äœã§ããïŒïŒããã©ã«ãã®ãã¥ãŒïŒãã¡ã»ãããªãã§ããŒãžã«ã¢ã¯ã»ã¹ããå Žåã«åŸããããã®ïŒãäºåã«ã¬ã³ããªã³ã°ãããªã¯ãšã¹ãã«ã¯ãšãªãã©ã¡ãŒã¿ãŒãããå Žåã¯ã¯ã©ã€ã¢ã³ãåŽã§æŽæ°ããããšãæ€èšããããšããå§ãããŸãã ããããããã¯ãã®SSGRFCãè¶ ããåé¡ã«ãªããŸãã
@dpfavandç§ãæ£ç¢ºãªããšãçµéšããŠããŸãïŒ CMSã®ããŒãžã«åºã¥ãåçããŒãžã«ãŒãã£ã³ã°ã䜿çšããŠ
@timneutkensãã©ããŒã¢ããã«æè¬ããŸãã ç§ã¯2ã€ã®æ¹æ³ãè©ŠããŸãããæåããŸããã§ããã æååãšããŠã¹ã©ã°å€ãæå®ããå Žåã¯ãåºæ¬çã«
getStaticPaths
ããããã«æž¡ãããŠããŸããgetStaticProps
ãã¹ãŠã§ã
ã±ãŒã¹1ããã¡ã€ã«pages/[...slug].jsx
æ³å®ããæååãšããŠã¹ã©ãã°ïŒexport async function unstable_getStaticPaths() { return [{ params: { slug: 'en/about' } }]; } export async function unstable_getStaticProps({ params }) { console.log('params', params); return { slug: params.slug }; }
äžèšã®å Žåã
params
getStaticProps
ã¯ç©ºã®ãªããžã§ã¯ãã§ãããslug
ããŒã¯ãããŸããããšããã§ãå°ããªäžçïŒ fastr_confã§ã話ãããã ãããããšãããããŸãã
ããïŒ NextjsããŒã ã¯ããã«å¯ŸåŠãå§ããŸãããçŸåšã®ã«ããªã¢ã®å®è£ ã«é¢ããããã€ãã®è¿œå ã®åé¡ã«å¯ŸåŠããããã®ãã±ãããéãããŠããŸãïŒ https ïŒ
@smnhç§ããã£ãŠããããšã¯ããã«ããšãšã¯ã¹ããŒããå®è¡ããåã«ãå ±æã³ã³ãã³ããããªãã§ããããŠJSONã«ä¿åããã¹ã¯ãªãããäœæããããšã§ãã 次ã«ããã®JSONãã¢ãžã¥ãŒã«ãšããŠããŒãžã«çŽæ¥ã€ã³ããŒãããŸãã
åæ§ç¯ã®å Žåãé¢é£ããã³ã³ãã³ããå€æŽããããšãã«Netlifyãã«ãããã¯ãããªã¬ãŒããããã«CMSã«Webhookãèšå®ããŸããã GetStaticPropsã¯ãããŒãžåºæã®ã³ã³ãã³ãããã§ããããã ãã§ãã
ããããšã@zeusdeux
NSïŒ
2çªç®ã®è³ªåã«ã€ããŠã¯ãèªåçã«è¡ãããŸãã 次ã®éçºãå®è¡ããã°ãæºåã¯å®äºã§ãã
ããããã¢ãžã¥ãŒã«ã«ãã£ãã·ã¥ããŠããCMSã®ããŒã¿ãå€æŽãããšããã£ãã·ã¥ãç¡å¹ã«ãªãã dev
ã«ãã£ãŠåå®è¡ãããŸãããnext.jsãåæ¢ããŠå床å®è¡ããããšã¯ãããŸãã:)
ããããã¢ãžã¥ãŒã«ã«ãã£ãã·ã¥ããŠããCMSã®ããŒã¿ãå€æŽãããšããã£ãã·ã¥ãç¡å¹ã«ãªãã
dev
ã«ãã£ãŠåå®è¡ãããŸãããnext.jsãåæ¢ããŠå床å®è¡ããããšã¯ãããŸãã:)
getStaticPaths
ã¯æ¬çªãã«ãã§ã®ã¿åŒã³åºãããããããã®é¢æ°ããåŒã³åºãããå Žåã«ã®ã¿ããã§ããã¡ãœããã«ã¢ãžã¥ãŒã«ç¶æ
ã§ãã£ãã·ã¥ããããã«æ瀺ã§ããŸãã
ããã誰ããç§ãšåãåé¡ã«ééãããã©ããã¯èŠãããšããããŸããã
unstable_getStaticProps
è€æ°ã®ã«ãŒãã«åãããŒãžããããšããŸãããïŒ
1. /providers/[category]/[city]
2. /providers/[category]
ãœãŒã¹ã³ãŒãã¯äž¡æ¹ã®ããŒãžã§åãã§ãããããè€è£œããå¿
èŠã¯ãããŸããã ãããã£ãŠãæåã®ãã¡ã€ã«ã«ããžãã¯ä»ãã®ãœãŒã¹ã³ãŒããå«ãŸããŠããå Žåã2çªç®ã®ãã¡ã€ã«ã¯export { default } from './[city]';
ããã«æåã®ãã¡ã€ã«ã®ã¿ãã€ã³ããŒãããŸãã
ãã ããgetStaticPropsããã®ããŒã¿ãæªå®çŸ©ã§ãããšãããšã©ãŒãã¹ããŒãããŸãã åãã³ãŒããäž¡æ¹ã®ãã¡ã€ã«ã«ããŒãã³ããŒãããšãæ©èœããŸãã
@homokyã¡ãœãããåãšã¯ã¹ããŒãããå¿ èŠããããŸãïŒ
export { default, unstable_getStaticProps } from './[city]';
ç§ã¯SSGãè©ŠããŠããŸããããéããããŸããã§ããã
以äžã®v9.2.1ã®ã³ãŒãã¯SSGã«ãªããŸããïŒ
function Page({ stars }) {
return <div>Next stars: {stars}</div>
}
Page.unstable_getStaticProps = async ctx => {
return { props: { stars: 5 } }
}
export default Page
next build
ããã®ã³ã³ãœãŒã«åºåã¯æ¬¡ã®ããã«è¡šç€ºãããŸãã
Page Size First Load
â â / 354 B 72.1 kB
...
λ (Server) server-side renders at runtime (uses getInitialProps or getServerProps)
â (Static) automatically rendered as static HTML (uses no initial props)
â (SSG) automatically generated as static HTML + JSON (uses getStaticProps)
@joostmeijles unstable_getStaticProps
ã¯ãããŒãžã³ã³ããŒãã³ãã«æ·»ä»ããã®ã§ã¯ãªãããšã¯ã¹ããŒãããå¿
èŠããããŸãã
export const unstable_getStaticProps = async () => {
return {
props: { stars: 5 }
}
}
@joostmeijles
unstable_getStaticProps
ã¯ãããŒãžã³ã³ããŒãã³ãã«æ·»ä»ããã®ã§ã¯ãªãããšã¯ã¹ããŒãããå¿ èŠããããŸããexport const unstable_getStaticProps = async () => { return { props: { stars: 5 } } }
ãããã§ãããã¯ããã解決ããŸãã
誰ããããã®ãšã³ãããŒãšã³ãã®å®çšçãªäŸãèŠããå Žåã¯ããã£ãããªãŒã«ã«ãŒããšSSGã䜿çšããŠïŒCMSããïŒåçããŒãžãäœæããŸãhttps://github.com/agility/agilitycms-next-starter- ssgã
ç§ã¯äœåºŠãå°æãããããä»ã®äººã«åœ¹ç«ã€ãããããªããšèããŸããã
zeit.co/nowã«ãããã€ãããšãã«ããã«ãäžã«getStaticProps
ã䜿çšããŠæ¬¡ã®APIã«ãŒãã«ã¢ã¯ã»ã¹ããã«ã¯ã©ãããã°ããã§ããïŒ å圢ãã§ããã«ã¯çµ¶å¯ŸURLãå¿
èŠã§ãã ããŒã«ã«ã§ã¯httpïŒ// localhost ïŒ3000ã§åäœã
ç§ãæ£ãããã°ãAPIã«ãŒãã¯ãµãŒããŒã¬ã¹é¢æ°ãšããŠãããã€ããããã«ãããã»ã¹äžã«æºåãã§ããŠããªããšæããŸããïŒ
httpãçµç±ããããããªãŒããŒããããã¯ããã«å°ãªããããAPIã«ãŒãã®é¢æ°ãçŽæ¥åŒã³åºãããšããå§ãããŸãã
httpãçµç±ããããããªãŒããŒããããã¯ããã«å°ãªããããAPIã«ãŒãã®é¢æ°ãçŽæ¥åŒã³åºãããšããå§ãããŸãã
ãã®ãããã¯ã«é¢ããããã¥ã¡ã³ãã§èªãããšãã§ãããªãœãŒã¹ã¯ãããŸããïŒ ç§ã¯zeit.co/nowãžã®ç§»è¡ã®æäžã§ã:)
æåéããé¢æ°ãã€ã³ããŒãããŠåŒã³åºããŸãã
import MyFunction from '../lib/somewhere'
export async function /* unstable_ */getStaticProps() {
const result = await MyFunction()
}
å¥ã®è³ªåïŒ getStaticProps
/ getStaticPaths
ãšgetServerProps
䞊ã¹ãŠäœ¿çšããããšã¯å¯èœã§ããïŒ ããšãã°ãSSGã䜿çšããŠäžéšã®ããŒãžãäºåã¬ã³ããªã³ã°ããããCDNãã£ãã·ã¥ã«ããŒãžãèŠã€ãããªãå ŽåãããŒãžããªã³ããã³ãã§çæããããã«SSRã«ãã©ãŒã«ããã¯ããŸããïŒ
getStaticProps
ã¯SSRã«ãã©ãŒã«ããã¯ããçµæããã£ãã·ã¥ã«è¿œå ããŸãã
getStaticProps
ã¯SSRã«ãã©ãŒã«ããã¯ããçµæããã£ãã·ã¥ã«è¿œå ããŸãã
@lfades ãç§ãããªããæ£ããç解ããŠãããªããç§ã¯ããã«ã€ããŠãšãŠãðã§ãããªããªããäºåã«æ°åããŒãžã調ã¹ãŠçæãã代ããã«ã人æ°ã®ããããŒãžã®ããã€ããäºåã«ã¬ã³ããªã³ã°ã§ããããã§ãã
ããããç§ãç解ããŠããããšã確èªããããã«... /products/[productId].js
åçãã¹ããŒãžããããšããŸãããã getStaticProps
ã getStaticPaths
ããã®çµæã®æ°ãéãããŠããå Žåã /products/123
ãCDNãã£ãã·ã¥ã«èŠã€ãããªããã©ããã瀺ããŠããŸãïŒããããªãã£ãããïŒ t in getStaticPaths
ïŒãSSRã«æ»ãã getStaticProps
å®è¡ããŠãçµæãéçããŒãžãšããŠãã£ãã·ã¥ããŸããïŒ
ãã©ããŒã¢ããã®è³ªåïŒ getStaticPaths
ããŸã£ããæäŸããªããŠããããã¯æ©èœããŸããïŒ
@flintinatuxã¯ããã¯ãð
getStaticPropsã¯SSRã«ãã©ãŒã«ããã¯ããçµæããã£ãã·ã¥ã«è¿œå ããŸã
getStaticProps
ã§ã¯res
ãªããžã§ã¯ããå€æŽã§ããªãããã404ãå®è¡ããæ¹æ³ããªããããããã¯åé¡ã§ããé¢æ°åŒã³åºãäžã«ãšã©ãŒãçºçããå Žåã¯ã200ãŸãã¯500ã«ãªããŸãã
ããã¯å€æŽãããäºå®ã§ããïŒ
@ davidbailey00éçãŠã§ããµã€ããäœæããå Žåã404ããŒãžã«ã¯ãã§ã«404ã¹ããŒã¿ã¹ã³ãŒãããããŸããã
ãã¡ãããå®å
šãªéçãšã¯ã¹ããŒããå®è¡ããå Žåããã¹ãŠãåãªããã¡ã€ã«ã§ãããããã¹ããŒã¿ã¹ã³ãŒããå®è¡ããæ¹æ³ã¯ãããŸããã getStaticProps
ã䜿çšããŠãã€ããªãããµã€ããZEIT Nowã«ãããã€ããããšã«ã€ããŠè©±ããŠããŸããããã«é¢ä¿ãªãããã¹ãŠã®ããŒãžãåçãã¹ã«äžèŽãããã®ã§ã¯ãªãã getStaticPaths
ãå°éãã404ããŒãžãæäŸããå¿
èŠãããããã§ãã
ããã¯ãNowã§ã®åäœã ãã§ã¯ãªãã next start
åãã§ãã
ãã ããåã«è¿°ã¹ãããã«ç¹°ãè¿ããŸããããã¯å®éšçãªãã®ã§ãããåäœã¯å€åããå¯èœæ§ããããŸãã
ãããã getServerProps
ãŸãã¯getInitialProps
404ããŒãžãæäŸããããšã¯å¯èœã§ã-å¿çã³ãŒããæ€èšãããšãã«getStaticProps
ãgetStaticPaths
ç¡èŠããå Žåãããã¯æ°ã«ãããµã€ãã«ãšã£ãŠå®å
šã«å®è¡äžå¯èœã§ãè¯ãSEOã
ããããã¹ããŒã¿ã¹ã³ãŒããåŠçããæ¹æ³ããã£ãšçŽ¹ä»ããŸãããã»ãšãã©ã®éçãµã€ãïŒCRAãªã©ïŒã¯/*
ãindex.html
ã«ã«ãŒãã£ã³ã°ããŸãã404ã¯ãŸã 200ã§ãã
ããã«ã¡ã¯ã¿ããªãç§ã¯ãŸã£ãããªè³ªåããããŸããç§ã¯ããã€ãã®ããŒãžãSSGããããã«æ°ãã[unstable_]getStaticProps
ã䜿çšããŠç°¡åãªãŠã§ããµã€ããæ§ç¯ããŠããŸãã ampãé€ããŠããããŸã§ã®ãšãããã¹ãŠæ£åžžã«åäœããŠã
ããŒãžã«[unstable_]getStaticProps
ãå«ãŸããŠããå Žåã amp
ã¯ç¡å¹ã«ãªããŸãã 次ã®v9.2.1ã§åäœããç°¡åãªäŸã次ã«ç€ºããŸããããã§ã次ã®ããšã確èªã§ããŸãã
import React from "react";
import { useAmp } from "next/amp";
export const config = { amp: `hybrid` };
const AmpExample = ({ date }) => {
const isAmp = useAmp();
return (
<>
<p>
Welcome to the {isAmp ? `AMP` : `normal`} version of the Index page!!
</p>
<p>date: {date}</p>
</>
);
};
/**
* If I get the dynamic data from getStaticProps,
* page is SSG render but AMP is disabled when accessing
* with `/ampExample?amp=1`
*/
export async function unstable_getStaticProps() {
return {
props: {
date: new Date().toISOString(),
},
};
}
/**
* If I get the dynamic data from getInitialProps,
* page is SSR render but AMP is disabled when accessing
* with `/ampExample?amp=1`
*/
// AmpExample.getInitialProps = () => {
// return { date: new Date().toISOString() }
// }
export default AmpExample;
ããŒãžSSG
ã«ããŒã¿ãšamp
æ©èœãããæ¹æ³ãç解ããã®ã«åœ¹ç«ã€ãã®ã¯ãããŸããïŒ
ããã«ã¡ã¯ã App
ã³ã³ããŒãã³ãïŒ _app.tsx
ïŒã®getStaticProps
ããµããŒãããã®ã¯ã©ãã§ããïŒã€ãŸãããã«ã段éã§ãã¹ãŠã®ããŒãžã³ã³ããŒãã³ãã®å
±éããŒã¿ããã§ãããããããªå Žåã¯ã©ãã§ããããïŒ
ããã«ã¡ã¯ã
App
ã³ã³ããŒãã³ãïŒ_app.tsx
ïŒã®getStaticProps
ããµããŒãããã®ã¯ã©ãã§ããïŒã€ãŸãããã«ã段éã§ãã¹ãŠã®ããŒãžã³ã³ããŒãã³ãã®å ±éããŒã¿ããã§ãããããããªå Žåã¯ã©ãã§ããããïŒ
@ pkral78å®éã®éçºç¶æ³ã§ã©ã®ããã«è§£æ±ºãããããäŒãããŸãã
ãé«æ¬¡ã³ã³ããŒãã³ãïŒHOCïŒãšããŠã®ã¬ã€ã¢ãŠãããšããã¢ãããŒãã§ã¬ã€ã¢ãŠããäœæããŸããïŒåŠç¿ããã¥ã¡ã³ãã«ã¯ãããããŸããð€·ââïžïŒã
ãšã«ãããç§ã¯æ¬¡ã®ãããªã¬ã€ã¢ãŠããäœæããŸããïŒåãªãäŸïŒïŒ
import React from "react";
import Head from "next/head";
const withSSGLayout = Page => {
const WithSSGLayout = props => {
return (
<>
<Head>
<title>My Web Page</title>
<link rel="icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link
href="https://fonts.googleapis.com/css?family=Roboto:400,700&display=swap"
rel="stylesheet"
/>
</Head>
<Page {...props} />
</>
);
};
WithSSGLayout.unstable_getStaticProps = async () => {
const pageStaticProps = Page.unstable_getStaticProps
? await Page.unstable_getStaticProps()
: {};
// Here you can make parent level queries too
return {
props: {
...pageStaticProps.props,
parentProp: `dynamic prop-${new Date().toISOString()}`,
},
};
};
return WithSSGLayout;
};
export default withSSGLayout;
ãããŠããã®ã¢ãããŒãã䜿çšãããããŒãžã§ãHOCãç°¡åã«è¿œå ã§ããŸãïŒ [unstable_]getStaticProps
ãšã¢ã³ããé£æºããŠããªãããšãæ瀺çã«ãšã¯ã¹ããŒãããå¿
èŠããããŸãïŒããé«ã¬ãã«ã®ãªã¯ãšã¹ããè¡ãããã®ãè¯ãæ¹æ³ããèŠã€ããŸããããã³ããŒãžããšã®SSGã¯ãšãªã
import React from "react";
import withSSGLayout from "../hocs/withSSGLayout";
export const config = { amp: `true` };
const Index = props => {
const { date, parentProp } = props;
return (
<div>
<h1>Example</h1>
<h3>Local Prop?: {date}</h3>
<h3>Parent Prop?: {parentProp}</h3>
</div>
);
};
// In theory you could do direct database queries
Index.unstable_getStaticProps = async () => {
// Here you can make page level queries
return {
props: {
date: new Date().toISOString(),
},
};
};
const IndexHOC = withSSGLayout(Index);
export const { unstable_getStaticProps } = IndexHOC;
export default IndexHOC;
ãããè¯ãã¢ãããŒãã§ãããã©ãããç解ããããšæããŸãã ç§ã®å Žåããã®ææ³ã䜿çšããŠã芪ã®ãªã³ã¯ãšããŒãžã®ã³ã³ãã³ãããšã«ã¯ãšãªãå®è¡ããŠããŸãã ã圹ã«ç«ãŠã°å¹žãã§ãã
@robertovgã³ãŒãã¯ããªãŒã·ã§ã€ã¯ãããŠãããããã¢ãžã¥ãŒã«ã¬ãã«ã§ãšã¯ã¹ããŒãããå¿ èŠããããŸãã ã¢ãã«åããæ¹æ³ã«ãããããå€ãã®ã³ãŒããã¯ã©ã€ã¢ã³ãåŽã«åºè·ãããŸãã
@timneutkensãã®å°ããªäŸã«å¯ŸããŠãããè¯ã解決çãææ¡ã§ããŸããïŒ ãªãããã®æ¹æ³ã§ãã¬ã€ã¢ãŠãã¬ãã«ã®SSGã¯ãšãªããšãããŒãžã¬ãã«ã®SSGã¯ãšãªãã®äž¡æ¹ãäœæããããšããŠããã®ã§ããã®HOCã¬ã€ã¢ãŠãã¢ãããŒãã«ã€ããŠèããŸããã
ç§ã«ãšã£ãŠã®äž»ãªå¶çŽã¯ãSSGããŒãžãšããŠããŒã¯ããããã«åããŒãžã«å¿ èŠãªã[unstable_] getStaticPropsãæ瀺çã«ãšã¯ã¹ããŒããããããšã§ããã
ã¢ã³ããšSSGãäºææ§ããããã©ããã«ã€ããŠãããå°ãæ å ±ãããã ããã°
ããããšãð
@robertovgãŸããã¬ã€ã¢ãŠããããŒã¿ããåé¢ããŸããå ±æã¬ã€ã¢ãŠãã®å Žåã次ã®ãããªåçŽãªãã®ã«ãªããŸãã
import Layout from '../components/layout'
const Page = () => (
<Layout>
<h1>Hello World!</h1>
</Layout>
)
export default Page
次ã«ã getStaticProps
ã®å Žåãå¥ã®ã¢ãžã¥ãŒã«ã®ã¡ãœããã䜿çšããŠå
±æããŒã¿ããã§ãããããããå®å
šãªäŸã¯æ¬¡ã®ããã«ãªããŸãã
import fetchSharedData from '../lib/fetch-shared-data'
import Layout from '../components/layout'
export const unstable_getStaticProps = async () => {
const sharedData = await fetchSharedData()
const pageProps = {...}
return { props: { ...sharedData, ...pageProps } }
}
const Page = () => (
<Layout>
<h1>Hello World!</h1>
</Layout>
)
export default Page
@robertovgãŸããã¬ã€ã¢ãŠããããŒã¿ããåé¢ããŸããå ±æã¬ã€ã¢ãŠãã®å Žåã次ã®ãããªåçŽãªãã®ã«ãªããŸãã
import Layout from '../components/layout' const Page = () => ( <Layout> <h1>Hello World!</h1> </Layout> ) export default Page
次ã«ã
getStaticProps
ã®å Žåãå¥ã®ã¢ãžã¥ãŒã«ã®ã¡ãœããã䜿çšããŠå ±æããŒã¿ããã§ãããããããå®å šãªäŸã¯æ¬¡ã®ããã«ãªããŸããimport fetchSharedData from '../lib/fetch-shared-data' import Layout from '../components/layout' export const unstable_getStaticProps = async () => { const sharedData = await fetchSharedData() const pageProps = {...} return { props: { ...sharedData, ...pageProps } } } const Page = () => ( <Layout> <h1>Hello World!</h1> </Layout> ) export default Page
ç§ã¯ãã®è§£æ±ºçãèŠãŠç解ããŠããŸãããç§ãæèµ·ããããšããŠããåé¡ã¯ãå
±æããŒã¿ã®äœ¿çšãã©ã®ããã«ã¹ã±ãŒãªã³ã°ãããã§ããã
ããšãã°ãããªããæã£ãŠããå Žåã¯<Header />
ããã¯äœ¿çšããŠããŸãsharedData
ãªã³ã¯ãããããã¬ã¹CMSããæ¥ãŠãããã®ããååŸããŸãã å°éå
·ãŸãã¯å¥ã®ãœãªã¥ãŒã·ã§ã³ã䜿çšããŠã <Layout />
åãšããŠ<Header />
ã泚å
¥ããå¿
èŠããããŸãã ãããŠãããã䜿çšããããã¹ãŠã®ããŒãžã«<Header />
ã€ã³ãžã§ã¯ã·ã§ã³ãç¹°ãè¿ãå¿
èŠããããŸãã
HOCã¢ãããŒãã§ã¯ã <Header />
1åè¿œå ããã ãã§ãã
ãã®ãããå¯èœã§ããã°ã³ãŒãã®éè€ãé¿ããããã«ã @ pkral78ã«ãã£ãŠæèµ·ããããã®ãè¯ãç¹ã ãšæããŸããã
ãã®ãããå¯èœã§ããã°ã³ãŒãã®éè€ãé¿ããããã«ã @ pkral78ã«ãã£ãŠæèµ·ããããã®ãè¯ãç¹ã ãšæããŸããã
ããã¯ç§ã®é ã®äžã«ãããŸããã _appããŒãžã«ã¯getStaticProps
ãå¿
èŠã§ããããã¯ãæåã®ããŒãžã®ã¬ã³ããªã³ã°äžã«1ååŒã³åºãããä¿åãããprops
ã次ã®ã¬ã³ããªã³ã°ãããããŒãžã«æž¡ããŸãã ãããããããé©åãªæŠå¿µã§ãããã©ããã¯ãŸã èããŠããŸãã
ãã®çš®ã®ãã®ãæå³ããããŠãŒã¹ã±ãŒã¹ã§ãããã©ããã¯ããããŸããããæ©èœããŠããªãããã§ãã
// /pages/[...slug].jsx
import ReactDOMServer from "react-dom/server";
export async function unstable_getStaticProps({ params: { slug } }) {
const filePath = "../content/" + slug.join("/") + ".mdx";
const { default: Component } = await import(filePath);
const content = ReactDOMServer.renderToStaticMarkup(<Component />);
return {
props: { title: slug.join(" "), content }
};
}
export default function Page({ title, content }) {
return (
<div>
<h1>{title}</h1>
<div dangerouslySetInnerHTML={{ __html: content }} />
</div>
);
}
æå³ããããŠãŒã¹ã±ãŒã¹ã§ã¯ãªãå Žåã§ããå°ãçããããšæããããšã©ãŒããã°ã«èšé²ããŸãã
[ warn ] ./pages/[...slug].jsx
Critical dependency: the request of a dependency is an expression
ç·šéïŒ
ãããããããŸãããç§ããããšãããã¯è§£æ±ºããŸã
const { default: Component } = await import(`../content/${slug.join("/")}.mdx`);
ããã¯ãã€ã³ããŒããã¡ã€ã«ã®ãã¹ãåçã§ããããšã«ã€ããŠäžå¹³ãèšã£ãŠããŸã
Jan Potomsã®[email protected]ã¯ã2020幎1æ30æ¥æšææ¥ã®00:29ã«æ¬¡ã®ããã«æžããŠããŸãã
ãã®çš®ã®ãã®ãã©ããããããªã
https://codesandbox.io/s/nifty-cache-jspqrã¯æå³ããããŠãŒã¹ã±ãŒã¹ã§ããã
ããŸããããªãããã§ãïŒ// /pages/[...slug].jsximport ReactDOMServer from "react-dom / server";
éåæé¢æ°ã®ãšã¯ã¹ããŒãunstable_getStaticPropsïŒ{paramsïŒ{slug}}ïŒ{
//ããã¯ã©ããããå®å šã§ããïŒ
const filePath = "../content/" + slug.joinïŒ "/"ïŒ+ ".mdx";
const {ããã©ã«ãïŒã³ã³ããŒãã³ã} = await importïŒfilePathïŒ;
const content = ReactDOMServer.renderToStaticMarkupïŒComponentïŒ;
æ»ã {
å°éå ·ïŒ{ã¿ã€ãã«ïŒslug.joinïŒ ""ïŒãã³ã³ãã³ã}
};
}
ããã©ã«ãé¢æ°ã®ãšã¯ã¹ããŒãPageïŒ{titleãcontent}ïŒ{
æ»ã ïŒ{é¡å}
ïŒ;
}æå³ããããŠãŒã¹ã±ãŒã¹ã§ã¯ãªãå Žåã§ãã次ã®ããã«èŠãããšã©ãŒããã°ã«èšé²ããŸãã
å°ãçãããïŒ[èŠå] ./ pages / [... slug] .jsx
éèŠãªäŸåé¢ä¿ïŒäŸåé¢ä¿ã®èŠæ±ã¯åŒã§ãâ
ããªããèšåãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããGitHubã§è¡šç€ºããŠãã ãã
https://github.com/zeit/next.js/issues/9524?email_source=notifications&email_token=AAADKRKOL34WKTG7J5QFRJ3RAIGPBA5CNFSM4JRPBEL2YY3PNVWWK3TUL52HS4DFVREXG43VMVBW63LNMVXHJKTDN5
ãŸãã¯è³Œèªã解é€ãã
https://github.com/notifications/unsubscribe-auth/AAADKRIWNA2DSMWFRGD453DRAIGPBANCNFSM4JRPBELQ
ã
ãã®ãããå¯èœã§ããã°ã³ãŒãã®éè€ãé¿ããããã«ã @ pkral78ã«ãã£ãŠæèµ·ããããã®ãè¯ãç¹ã ãšæããŸããã
ããã¯ç§ã®é ã®äžã«ãããŸããã _appããŒãžã«ã¯
getStaticProps
ãå¿ èŠã§ããããã¯ãæåã®ããŒãžã®ã¬ã³ããªã³ã°äžã«1ååŒã³åºãããä¿åãããprops
ã次ã®ã¬ã³ããªã³ã°ãããããŒãžã«æž¡ããŸãã ãããããããé©åãªæŠå¿µã§ãããã©ããã¯ãŸã èããŠããŸãã
@ pkral78 ãNextã§å®è£ ãããŠãããšæ³åããã»ãšãã©ã®SSGãµã€ãã§ããå ±éã®éšåãïŒããããŒãããã¿ãŒããµã€ãããŒãªã©ïŒãå¿ èŠãªããã§ããå¯èœæ§ããããŸãã ãŸããå¿ èŠã«å¿ããŠ_appã§ãã®å ±ééšåã®ã¯ãšãªãäœæããåããŒãžã§æåã§å®è¡ããªããŠãåããŒãžã§äœ¿çšã§ããããã«ããªãã®ã¯ãªãã§ããã
ç§ã®å¯äžã®æžå¿µã¯ãããã_app.js
ã«å
¥ãããšãããŒãžã«ãã£ãŠã¯è€æ°ã®ãå
±ééšåããæã€ããšãã§ããªããšããããšã§ãã ç§ãè©Šäœãããã¢ã€ãã¢ããç§ã¯ç§ãåŒã°ããçç±ã ããšããããã¯ç§ãã¡ã¯ããªããã¬ã³ããªã³ã°ããããŒãžã®çš®é¡ã«å¿ããŠãè€æ°ã®ã¬ã€ã¢ãŠããæã€ããšãã§ããããã«ãªãã®ã§ãã¬ã€ã¢ãŠãã«ãããæã£ãŠã§ããããã«ãããã£ãã®withSSGLayout
ã«ç§ã®HOCã¯ãSSGããŒãžã ãã§ãªããSSRãšå®å
šã«ã¯ã©ã€ã¢ã³ãããŒã¹ã®ããŒãžããŸãã¯è€æ°ã®SSGLayoutãèšç»ããŠããããã§ããããã¯ãã¬ã€ã¢ãŠãã芪ã®getStaticProps
ã¡ãœãããæ
åœã§ããå Žåã«å®è¡ã§ããŸãã
ãšã«ãããNextã«SSGããããšãããããçš®é¡ã®Webãµã€ãã®ããŒã«ã«ãªããŸãð
@Janpot https://github.com/zeit/next.js/issues/9524#issuecomment -580012327
import()
åçãã¹ã䜿çšããªãããšã匷ããå§ãããŸãã ãã¹ã®äžã«ãããã¹ãŠã®å¯èœãªãã¡ã€ã«ãJSãã³ãã«ã«ãã³ãã«ããããããããšã§ãã«ãããã©ãŒãã³ã¹ã倧å¹
ã«äœäžãããŸãã
@timneutkens確ãã«ãçã«ããªã£ãŠããŸãã getStaticProps
ã¯ããã¡ã€ã«ã·ã¹ãã ã§ã¯ãªããå€éšAPIãã¯ãšãªããããšã ããç®çãšããŠããŸããïŒ
@Janpotã¯ãã¡ã€ã«ã·ã¹ãã ããèªã¿åãããšãã§ããŸãããå€ãã®å Žåãå€éšAPIã«ã¯ãšãªãå®è¡ããããšã«ãªããŸãã
@timneutkensããããŸããã @next/mdx
ã«é Œãã®ã§ã¯ãªãã @mdx-js/runtime
ã䜿çšããæ¹ãè¯ããšæããŸãã
import ReactDOMServer from "react-dom/server";
import { promises as fs } from "fs";
import MDX from "@mdx-js/runtime";
export async function unstable_getStaticProps({ params: { slug } }) {
const mdxContent = await fs.readFile(`./content/${slug.join('/')}.mdx`, {
encoding: "utf-8"
});
const content = ReactDOMServer.renderToStaticMarkup(<MDX>{mdxContent}</MDX>);
return {
props: { title: slug.join(" "), content }
};
}
export default function Page({ title, content }) {
return (
<div>
<h1>{title}</h1>
<div dangerouslySetInnerHTML={{ __html: content }} />
</div>
);
}
@JanpotããïŒ ãã¬ãŒã³ãªããŒã¯ããŠã³ã䜿çšããããšãã§ããŸããããã¯ãnextjs.org / docsã«å¯ŸããŠè¡ãããšã§ãã
https://github.com/zeit/next.js/issues/9524#issuecomment -580207073ã«é¢ããŠã¯ãçŸåšSSRã§Nextã䜿çšããŠããã®ãšãŸã£ããåãã§ãã ã¬ã€ã¢ãŠãã¬ãã«ã§å®è¡ãããGraphQLãªã¯ãšã¹ããããããã®ã³ã³ãã³ãã¯ã¢ããªã®å ±éã³ã³ããŒãã³ãïŒNavbarãFooterãããã³åçãªåïŒãšå ±æãããŸãã 次ã«ãåçãªåã¯éåžžãããŒãžåºæã®ã³ã³ãã³ãã«å¯ŸããŠå¥ã®GraphQLãªã¯ãšã¹ããäœæããŸãã
ãããã£ãŠããããåå©çšããæ¹æ³ãããããšã¯éèŠã§ããããã«æãããŸãããããã®å ±éããŒã¿ããã§ããããããã«ãåããŒãžã§ã³ãŒããè€è£œããå¿ èŠã¯ãããŸããã
ããïŒ
ç§ã¯ããã§ããªãæ°ããã§ãã ã¢ããªãNextJSã«ç§»è¡ããäœæ¥ãéå§ããŸããã
ãã®æ©èœãã倧ããªæ©æµãåããåºæ¬çãªãŠãŒã¹ã±ãŒã¹ããããŸã-è€æ°ã®èšèªããŒãžã§ã³ã ç§ãåãçµãã§ããWebã¢ããªã«ã¯ã1æ¥ããã100.000以äžã®ããŒãžãã¥ãŒãæã€16ã®èšèªããŒãžã§ã³ããããããšãã°ã©ã³ãã£ã³ã°ããŒãžãéçã«çæã§ããããšã¯çŽ æŽãããããšã§ãããåé¡ã¯ã«ãŒãã£ã³ã°ã§ãã
ãµãŒããŒãµã€ãã¬ã³ããªã³ã°ã䜿çšãããšããªã¯ãšã¹ãããããŒãŸãã¯Cookieãèªã¿åããé©åãªèšèªããŒãžã§ã³ãã¬ã³ããªã³ã°ã§ããŸãããããããªããšã/ enã/ deã/ frãªã©ã®ãã¹ãŠã®ããŒãžã§ã³ã®ãã¹ãäœæããã/ãã§NextJSã«ãªãã€ã¬ã¯ããããå¯äžã®ãœãªã¥ãŒã·ã§ã³ã§ããïŒ
ReactDOMServer.renderToStaticMarkup
ã«ã€ããŠåŠç¿ããåŸã unstable_getStaticProps
é¢æ°ã«è¿œå ããŸãããã€ã³ã¿ã©ã¯ãã£ããŸã§ã®æéãšæœåšçãªæåã®å
¥åé
延ã®æ倧å€ã倧å¹
ã«æ¹åããããããïŒã¢ãã€ã«ïŒPageSpeedã¹ã³ã¢ã96ãã100ã«åäžããããšãããããŸããã ã
JavaScriptãªãã§ããŒãžã«ã¢ã¯ã»ã¹ã§ããæ£åžžã«èªã¿èŸŒãŸãããããSSGã䜿çšããŠããã«ãããããããReactã¯ããŒãžã®èªã¿èŸŒã¿ã§äœæ¥ãè¡ã£ãŠããããã§ãã
ããã¯Reactã«é¢ããç§ã®ç解ã®æ¬ åŠãããããŸããããJavaScriptã䜿çšããå Žåãšäœ¿çšããªãå Žåã®ããã©ãŒãã³ã¹ã¯åãã§ãããã³ã³ããŒãã³ãã®äºåã¬ã³ããªã³ã°ã圹ç«ã€ãšã¯æããŸããïŒSSGãè¡ã£ãŠããããšã ãšæããŸããïŒã
äºæããããã®ããã°ããŸãã¯ç§ãééã£ãŠããããšã¯ãããŸããïŒ
äºåã³ãããïŒ https ïŒ httpsïŒ
3AïŒ
2FïŒ
2F5e310826bcf5030008a91209--josephduffynextjs.netlify.comïŒ
2FpostsïŒ
2Fgathered-1-0-1 mobile
ã³ãããïŒ https ïŒ
ã³ãããåŸïŒ https ïŒ httpsïŒ
3AïŒ
2FïŒ
2F5e3371beda1b8f0009368ef9--josephduffynextjs.netlify.comïŒ
2FpostsïŒ
2Fgathered -1-0-1 mobile
@JosephDuffy
ãã®ãããSSGã䜿çšããŠããã«ãããããããReactã¯ããŒãžã®èªã¿èŸŒã¿ã§äœæ¥ãè¡ã£ãŠããããã§ãã
ããã¯DOMã最ããŸãã åºæ¬çïŒ
å¯äœçšãã€ãã³ããã³ãã©ãŒããªããªã©ãã³ã³ãã³ããæ¬åœã«éçã§ããå Žåã¯ãæé 2ãš3ã¯äžèŠã§ãã ããªãã®æ¹æ³ã§ã¯ãåºæ¬çã«ã³ã³ããŒãã³ãããªãŒã1ã€ã®å±æ§ãæã€1ã€ã®ã³ã³ããŒãã³ãã«æžãããŸããããã¯ãReactãã¬ã³ããªã³ã°ããŠãã€ãã¬ã€ãããã®ã«éåžžã«é«éã§ãã ïŒ+ dangerouslySetInnerHTM
ã¯æ°Žåè£çµŠäžã¯ç¡èŠãããŸãïŒ
<div dangerouslySetInnerHTML={{ __html: props.htmlContent }} />
ã€ãã³ããã³ãã©ãŒãšå¯äœçšã¯ãã®ã¡ãœããã§ã¯æ©èœããªãããšã«æ³šæããŠãã ããã
ç·šéïŒ
1ã€ã®ã¢ã€ãã¢ã¯ã getStaticProps
ãéçhtmlãè¿ãå Žåã«ãããŒãžã®ããã©ã«ãã®ãšã¯ã¹ããŒããçç¥ã§ããããã«ããããšã§ãã NS
export async function unstable_getStaticProps() {
// ...
return {
props: { dangerouslySetInnerHTML: { __html: '<div>static content</div>' } }
};
}
ã¯ã©ã€ã¢ã³ãåŽã§ã¬ã³ããªã³ã°ããå¿
èŠã¯ãªããããnext.jsã¯ãã®ã©ã³ã¿ã€ã ãããŒãžããé€å€ãã getStaticProps
è¿ããhtmlãã€ã³ã©ã€ã³åããã ãã§æžã¿ãŸãã ãŸããnext.jsã«ãŒãããŒãã§dangerouslySetInnerHTML
ã䜿çšãããå Žåãšåãããã«æ©èœããŸãã
ããã»ã©åŒ·åã§ã¯ãããŸããããéšåçãªæ°Žåãããå®è£
ãç°¡åã ãšæããŸãã ããã§Reactèªäœã®çšèªãåå©çšãããšããã®æ©èœãã©ã®ããã«æ©èœãããã«ã€ããŠã®æ··ä¹±ãæžããããšãã§ããŸãã
éçãµã€ããNext.jsã«ç§»è¡ããããšããŠããŸãããããã°æçš¿ã®ãã¹ãŠã®.htmlããªã¢ã³ãã.htmlã§çµãããªãããŒãžã§ã³ã«ãªãã€ã¬ã¯ãããããšæããŸãã getStaticProps
ã¯çŸåšã³ã³ããã¹ããååŸããŠããªãããã§ãããã®ãããçä¿¡ã¹ã©ãã°ãšãªãã€ã¬ã¯ãã®ãã§ãã¯ãå®è¡ã§ããŸããã getStaticProps
ãå®å
šãªã³ã³ããã¹ããååŸããŠãæ¡ä»¶ä»ãã®åŠçãå®è¡ã§ãããšäŸ¿å©ã§ãã
@nodabladamã«ã¹ã¿ã ã«ãŒãRFCïŒïŒ9081ãæ¢ããŠããããã§ãã
ãã®RFCã䜿çšãããšã次ã®ãããªãã®ãå®çŸ©ã§ããŸãã
// next.config.js
module.exports = {
redirects() {
return [
// Redirect from the old HTML version of a blog post
{
source: "/blog/:post.html",
destination: "/blog/:post",
permanent: true
}
];
}
};
çŸåšã experimental
ããŒã§ãã®æ©èœãè©Šãããšãã§ããŸãã
// next.config.js
module.exports = {
experimental: {
redirects() {
// ...
}
}
};
ç§ã®ãããžã§ã¯ãïŒçŽ8KããŒãžïŒã«getStaticPropsãšgetStaticPathNamesãå®è£ ããŸããã
ãã ããåºåãã¡ã€ã«ã¯ããããã€ããšã®ãã¡ã€ã«ã®10Kå¶éã«ã«ãŠã³ããããŸãã 8KããŒãžã§ã¯ãåããŒãžã«ãjsonãã¡ã€ã«ãå«ãŸããããã16Kã®åºåãã¡ã€ã«ãåŸãããŸãã
ãã®å¶éãå¢ããèšç»ã¯ãããŸããïŒ ãŸãã¯ããã®å¶éãåé¿ã§ããŸããïŒ
ç§ã¯åãåé¡ãæ±ããŠããŸãã
圌ãããã®å¶éãåŒãäžããããšããŠããããšã¯ç解ããŠããŸããããã€å±éããããã¯ããããŸããã
ãããã£ãŠããã¹ãŠã®ããŒãžã§getStaticPropsã䜿çšããäžéšã®ããŒãžã§ã®ã¿getStaticPathsã䜿çšããŠæ©èœããŸãïŒç§ã®è£œåããŒãžã¯å šããŒãžã®70ïŒ ãçæãããããgetStaticPathsãå ¥ããŸããã§ããïŒã ç§ã¯å¶éãäžåã£ãŠããŸãããããã¯å®ç§ã§ã¯ãããŸãããæåã®ããŒãã¯éåžžã«é·ãã404ãšã©ãŒãåŠçããã®ãå°é£ã§ãã
ç§ã¯åãåé¡ãæ±ããŠããŸãã
圌ãããã®å¶éãåŒãäžããããšããŠããããšã¯ç解ããŠããŸããããã€å±éããããã¯ããããŸããããããã£ãŠããã¹ãŠã®ããŒãžã§getStaticPropsã䜿çšããäžéšã®ããŒãžã§ã®ã¿getStaticPathsã䜿çšããŠæ©èœããŸãïŒç§ã®è£œåããŒãžã¯å šããŒãžã®70ïŒ ãçæãããããgetStaticPathsãå ¥ããŸããã§ããïŒã ç§ã¯å¶éãäžåã£ãŠããŸãããããã¯å®ç§ã§ã¯ãããŸãããæåã®ããŒãã¯éåžžã«é·ãã404ãšã©ãŒãåŠçããã®ãå°é£ã§ãã
圌ããããã«å¶éãåŒãäžããããšãé¡ã£ãŠããŸãããããã20Kã«ãªããªãããšãé¡ã£ãŠããŸã..ããã¯é·æçã«ã¯ç§ã«ãšã£ãŠååã§ã¯ãªãã§ãããã
getStaticPathsã§æåã®ããŒãæéãé¿ããããZeitNow以å€ã®ä»ã®ãœãªã¥ãŒã·ã§ã³ãæ¢ãå¿ èŠããããããããªã
Next.jsã¯ãgetServerPropsã®åŒã³åºãçµæãè¿ãAPIãšã³ããã€ã³ããèªåçã«å ¬éããŸãã [...] Next.jsã¯ããã®å ¬éãããAPIãšã³ããã€ã³ãããã§ããããŠãããŒãžãã¯ã©ã€ã¢ã³ãåŽã«ã¬ã³ããªã³ã°ããããã«å¿ èŠãªå°éå ·ã«å€æãããJSONããŒã¿ãååŸããŸãã
Next.jsã¯ãå®éã®ã«ãŒãå€æŽãå®è¡ããŠããŒãžã³ã³ããŒãã³ããã¬ã³ããªã³ã°ããåã«ããã®ãšã³ããã€ã³ãããããŒã¿ããã§ããããŸãïŒå°ãªããšãããã©ã«ãã§ã¯ãä»ã®æ¹æ³ã§ãããè¡ãããšã¯ã§ããŸããïŒã ãã®ãããç¹å®ã®ããŒãžãéçã«çæãããããããŠãŒã¶ãŒã¯éåžžã«ãã³ãã³ãšãããµã€ããäœéšããå¯èœæ§ããããŸãããSSRããŒãžãžã®ãªã³ã¯ãã¯ãªãã¯ãããšãã«ãŒããå€æŽãããå°ãåã«çªç¶ãµã€ããããã³ã°ãããŸãã
ã³ã³ããŒãã³ãã_first_ã§ããŒãããŠãããŒãã€ã³ãžã±ãŒã¿ãŒãã¢ãã¡ãŒã·ã§ã³åããããã¬ãŒã¹ãã«ããŒãªã©ãå ¥åã§ããããã«ããããã®æšå¥šãããæ¹æ³ã¯ãããŸããïŒ ïŒçŸåšã®ããŒãžã«è¿œå ãã代ããã«ãïŒããã§ãªãå Žåã¯ãæ°ããææ¡ãããæ©èœã«é¢é£ããå¯èœæ§ããããŸããïŒ getInitialPropsãšrenderã¡ãœããå ã®ããã¯ã®çµã¿åããã䜿çšããŠãããéæããŸããããé¢åã«æããŸãã
ãã®UXãã¿ãŒã³ïŒã€ã³ã¹ã¿ã³ãããŒãžã¹ã€ããïŒã¯å€ãã®äººïŒã»ãšãã©ïŒïŒã«å¥œãŸããŠãããšæããŸãããNext.jsã䜿çšããäŸã¯ãŸã èŠãŠããŸããã ãã¬ãŒã ã¯ãŒã¯ã䜿çšããŠããæ°æ¥ããçµã£ãŠããªãã®ã§ãééã£ãŠããå Žåã¯èšæ£ããŠãã ããã
æ°æ©èœã«æ¬åœã«è奮ããŠããŸãïŒ ãç²ãæ§ã§ããã
@nicoqh ããã³ã°ã¯çŸåšã®getInitialProps
çºçãããããããŒãžé·ç§»ã«é¢ããæžå¿µã¯SSGã«åºæã®ãã®ã§ã¯ãããŸããã nprogress
ã䜿çšããŠãå°ãªããšã次ã®ããŒãžã®èªã¿èŸŒã¿äžã«é²è¡ç¶æ³ããŒãäžéšã«è¡šç€ºããŸããã説æããŠããå
容ã«è¿ãããã«èãããæ£åœãªããŒãžé·ç§»ããããã®äŸã衚瀺ãããŸãã èªåã§è©Šããããšã¯ãããŸããããå¿
èŠãªãã®ã«åœ¹ç«ã€ããšãé¡ã£ãŠããŸãã
https://github.com/zeit/next.js/tree/canary/examples/with-next-page-transitions
è¿ãããjsonãã¡ã€ã«/_next/data/BUILD_ID/<file>.json
ã¯assetPrefixãå°éããŠããªãããã§ãã ããã«ãããæ¬çªç°å¢ã§ã¯ãã¡ã€ã«ã404ã«ãªããŸããããã¯ããã¹ãŠã®_nextãCDNãééããã¢ã»ããã§ãããšæ³å®ããã»ããã¢ãããããããã§ãã ãããã®jsonãã¡ã€ã«ã¯ãæçµçã«ã¯assetPrefixïŒCDNïŒãä»ããŠã«ãŒãã£ã³ã°ããå¿
èŠããããŸããïŒ
ç§ã¯åãåé¡ãæ±ããŠããŸãã
圌ãããã®å¶éãåŒãäžããããšããŠããããšã¯ç解ããŠããŸããããã€å±éããããã¯ããããŸããã
ãããã£ãŠããã¹ãŠã®ããŒãžã§getStaticPropsã䜿çšããäžéšã®ããŒãžã§ã®ã¿getStaticPathsã䜿çšããŠæ©èœããŸãïŒç§ã®è£œåããŒãžã¯å šããŒãžã®70ïŒ ãçæãããããgetStaticPathsãå ¥ããŸããã§ããïŒã ç§ã¯å¶éãäžåã£ãŠããŸãããããã¯å®ç§ã§ã¯ãããŸãããæåã®ããŒãã¯éåžžã«é·ãã404ãšã©ãŒãåŠçããã®ãå°é£ã§ãã圌ããããã«å¶éãåŒãäžããããšãé¡ã£ãŠããŸãããããã20Kã«ãªããªãããšãé¡ã£ãŠããŸã..ããã¯é·æçã«ã¯ç§ã«ãšã£ãŠååã§ã¯ãªãã§ãããã
getStaticPathsã§æåã®ããŒãæéãé¿ããããZeitNow以å€ã®ä»ã®ãœãªã¥ãŒã·ã§ã³ãæ¢ãå¿ èŠããããããããªã
@erhankaradenizãš@ziltoshã¯ãäžè¬çã«éåžžã«ããã«å±éããå¿ èŠããããŸãã ã§ããã ãæ©ããµããŒããå¿ èŠãªå Žåã¯ãçŽæ¥ç§ã«pingãããã support @ zeit.coã«é£çµ¡ããŠ
ç§ã¯åãåé¡ãæ±ããŠããŸãã
圌ãããã®å¶éãåŒãäžããããšããŠããããšã¯ç解ããŠããŸããããã€å±éããããã¯ããããŸããã
ãããã£ãŠããã¹ãŠã®ããŒãžã§getStaticPropsã䜿çšããäžéšã®ããŒãžã§ã®ã¿getStaticPathsã䜿çšããŠæ©èœããŸãïŒç§ã®è£œåããŒãžã¯å šããŒãžã®70ïŒ ãçæãããããgetStaticPathsãå ¥ããŸããã§ããïŒã ç§ã¯å¶éãäžåã£ãŠããŸãããããã¯å®ç§ã§ã¯ãããŸãããæåã®ããŒãã¯éåžžã«é·ãã404ãšã©ãŒãåŠçããã®ãå°é£ã§ãã圌ããããã«å¶éãåŒãäžããããšãé¡ã£ãŠããŸãããããã20Kã«ãªããªãããšãé¡ã£ãŠããŸã..ããã¯é·æçã«ã¯ç§ã«ãšã£ãŠååã§ã¯ãªãã§ãããã
getStaticPathsã§æåã®ããŒãæéãé¿ããããZeitNow以å€ã®ä»ã®ãœãªã¥ãŒã·ã§ã³ãæ¢ãå¿ èŠããããããããªã@erhankaradenizãš@Ziltoshã¯ãäžè¬çã«éåžžã«ããã«å±éããäºå®ã§ãã ã§ããã ãæ©ããµããŒããå¿ èŠãªå Žåã¯ãçŽæ¥ç§ã«pingãããã support @ zeit.coã«é£çµ¡ããŠ
ããããšã@kvangundy
ãã®åé¡ã«ã€ããŠTwitterã§é£çµ¡ããŸãã;-)
@erhankaradeniz代ããã«[email protected]ã«ã¡ãŒã«ãéä¿¡ã§ããŸããïŒ ããããã°ãããã¯ç§ãã¡ã®ã·ã¹ãã ã«æ£ããè¡ãçããŸãã
@flintinatux ã
ç§ã¯ããããã®åé¡ã§æ±ãããã€ããã¯ãªããšæããŸããããã¯ããããããã¯ããå€ããŠããããšãæå³ããã®ã§ãç§ã¯ãããè°è«ããããã«ã©ããä»ã®å ŽæãèŠã€ããã§ããã:)
getInitialPropsãgetStaticProps
ãšgetServerProps
ã«åå²ããã¢ãããŒãã¯ãã¯ããã«ã¯ãªãŒã³ã ãšæããŸãã ããããŠãŒã¹ã±ãŒã¹ã«ã©ã®ããã«åœ±é¿ãããã«ã€ããŠè³ªåããããŸãã
2ã€ã®å¥ã
ã®ãã«ããäœæããããšæããŸãã1ã€ã¯è£œåãµã€ãçšã®éçããŒãžã§ã³ã§ããã1ã€ã¯ç·šéç°å¢çšã®SSRã䜿çšããããŒãžã§ã³ã§ãã
ãã«ãã«å¿ããŠãéçã¡ãœãããšããŠgetStaticProps
ãšgetServerProps
ãæ¡ä»¶ä»ãã§ã¢ã¿ããã§ãããšèããŠããŸããïŒhttps://github.com/zeit/next.js/issues/9524#issuecomment-ãšåæ§ïŒã 558617056ïŒã§ãããæ¡ä»¶ä»ãã§ãã®ãŸãŸãšã¯ã¹ããŒãã§ãããã©ããã¯ããããŸããã ãã«ãã«å¿ããŠåç/éçããµããŒãã§ãããã©ããã«ã€ããŠäœãã¢ã€ãã¢ã¯ãããŸããïŒ
ãã®äºã«ä»ããŠã¯ïŒ
RFCã¯ãåŸã§å€æŽãåæ ããããã«æŽæ°ãããŸãããã¢ããªã§ã®å®éã®äœ¿çšãç¹°ãè¿ããŸãã
ãã«ãæã«äžæãªã«ãŒãããã£ããããããã«ãããçš®ã®ã¯ã€ã«ãã«ãŒãã«ãŒãã䜿çšããæ¹æ³ãããã®ã ãããã ããšãã°CMSããŒã¿ããéçããŒãžãã¬ã³ããªã³ã°ã§ããã®ã¯çŽ æŽãããããšã§ããã誰ããæ°ããã¢ã€ãã ãè¿œå ããå Žåã¯ã©ããªããŸããïŒ ãã®ããã®éçããŒãžã¯ãããŸããã ãã®åé¡ã¯é·ãéç§ã®é ãæ©ãŸããŸããã
éçããŒãž_pages / [slug] .js_ãã¬ã³ããªã³ã°ããåçã«ãŒããèšå®ããŸããã _getStaticPaths_ã¯ãéçã«ã¬ã³ããªã³ã°ããããã¹ãŠã®ããŒãžãååŸããŠããŸãã ããŒã¿ãã¯ãšãªããŠã¬ã³ããªã³ã°é¢æ°ã«æž¡ãããã®_getStaticProps_ããããŸãã _getStaticPaths_ã§æå®ããããã¹ãŠã®ããŒãžã¯ããã«ãæã«_.next / server / static_å ã§HTMLãã¡ã€ã«ãšããŠã¬ã³ããªã³ã°ãããŸãã çŽ æŽãããïŒ
ä»ãç§ã¯npm run start
ãšãããã®ããŒãžãå¿
èŠã«å¿ããŠå®è¡ããŸãã ãã ããæ¬ èœããŠããURLïŒ_ / foo_ãªã©ïŒãèŠæ±ãããšã_ãnext / server / static_å
ã«æ°ããéçHTMLãã¡ã€ã«ãšJSONãã¡ã€ã«ãçæãããŸãã ããã¯è¯ããªãã ãµãŒããŒãä»ã®ãã¹ãŠã®URLã_pages / _error.js_ã«ãªãã€ã¬ã¯ãããããã«ããã«ã¯ã©ãããã°ããã§ããïŒ
https://github.com/zeit/next.js/issues/9524#issuecomment -582777067
ããã«ã€ããŠã説æããŸãã
ä»ãç§ã¯npm run startãå®è¡ãããããã®ããŒãžãå¿ èŠã«å¿ããŠå®è¡ããŸãã ãã ããæ¬ èœããŠããURLïŒ/ fooãªã©ïŒãèŠæ±ãããšã.next / server / staticå ã«æ°ããéçHTMLãã¡ã€ã«ãšJSONãã¡ã€ã«ãçæãããŸãã ããã¯è¯ããªãã ãµãŒããŒãä»ã®ãã¹ãŠã®URLãpages / _error.jsã«ãªãã€ã¬ã¯ãããããã«ããã«ã¯ã©ãããã°ããã§ããïŒ
ããã¯ãŸã å®è¡äžã§ãããçŸæç¹ã§ã¯äºæããªãåäœã§ã¯ãããŸããã
ç¹°ãè¿ãã«ãªããŸãããå®éšçãªæ©èœã䜿çšããŠããããšãæãåºããŠãã ãããåäœã¯ãã€ã§ãå€æŽãããå¯èœæ§ããããŸãã å®å®ããŠããªããšãã«ããã䜿çšãããšãç¶æ³ãå€åãããã¹ãŠã®ããŒãžã§ã³éã§äžæããå¯èœæ§ããããŸãã
@timneutkensããããšãïŒ ç§ã¯äžå®å®ããç解ããŠããŸãã ããã管çããæ¹æ³ãç¥ã£ãŠããŸããïŒ ã³ãŒãã調ã¹ãŠã_unstable_getStaticProps_å ã§ãšã©ãŒãã¹ããŒãããšããšã©ãŒããŒãžã衚瀺ãããããšã«æ°ä»ããŸããã ããã¯è¯ãæ¹æ³ãããããŸããã ãšã©ãŒããã®ãŸãŸ_pages / _error.js_ã«æž¡ãæ¹æ³ãå¿ èŠã§ãã 404ãéä¿¡ããããšæããŸãã500ã«ãªããŸãã
以åã«ä»ã®ã¹ã¬ããã§ãããäœåºŠãæçš¿ããŸããããã_ errorã«ç§»åããããšããã®ã¯äºæããªãåäœã§ããçŸæç¹ã§ã¯ãããŒãžã¯404ç¶æ
ãã¬ã³ããªã³ã°ããã¯ãã§ãã if(!data.something) { return <My404Component /> }
ãšèšã£ãã ãã§ã My404Component
ã¯noindex
ã¡ã¿ã¿ã°ãèšå®ããå¿
èŠããããŸãã
æ¬åœã«ïŒ ããã¥ã¡ã³ãã§ã¯ã404ã«_pages /_error.js_ã䜿çšããããã«æ確ã«æ瀺ãããŠããŸãã
åç §ïŒ https ïŒ
@ jiv-eã¯ã次ã®åå ã«ãã404ã®å Žåã§ãã
åçã«ãŒããããå Žåã¯ãç§ãèšã£ãããã«ã404ãã®ã±ãŒã¹ãåŠçããå¿ èŠããããŸããããšãã°ã httpsïŒ //nextjs.org/docs/advanced-features/custom-error-page#reusing -the-built-in-error-ããŒãž
ãšã£ãïŒ ããããšãïŒ
getStaticProps
ã䜿çšããŠããã«ãæã«ç¿»èš³/èšèªããŒããã§ããããããšæããŸããããã¯ãæã«1ã2åãããã«ã¯å¹Žã«1åãå€æŽãããå¯èœæ§ãé«ãããã§ãã ãŸããDOMå
ã®JSON /å°éå
·ãšããŠããããå¿
èŠãšããŸããã åé¡ã¯ãããŒãå®éã«äœ¿çšããã³ã³ããŒãã³ãã«ããªãŒãäžã£ãŠæž¡ããããªããšããããšã§ã-ç§ã®ãŠãŒã¹ã±ãŒã¹ã«ã¯ã©ã®ãããªã¢ãããŒããé©ããŠããŸããïŒ
useTranslationïŒïŒããã¯ïŒãŸãã¯HOCïŒãšã³ã³ããã¹ãïŒ
AppTree
ãNextGetStaticPropsã³ã³ããã¹ãïŒ getStaticProps({ AppTree })
ïŒã®äžéšã«ãªããšäŸ¿å©ã§ãã ããããªããšãssgã§apollos getDataFromTree
ãããªãã®ãå®è¡ããããšã¯ã§ããŸããã
çŸæç¹ã§ã¯ãgetStaticPropsã§AppTreeãã©ããŒãµã«ãèš±å¯ããäºå®ã¯ãããŸãããããã¯ãããã©ãŒãã³ã¹ã«éåžžã«æªãããã§ãïŒäŒæ¥ããã®äžè²«ãããã£ãŒãããã¯ïŒã getStaticPropsãããŒãžã«è¿œå ããŠãã_appã®getInitialPropsãééããŠæ®µéçã«æ¡çšã§ãããããApolloã§å®éã«æ©èœããŸãã
amp: 'hybrid'
ãšSSGæ©èœãåæã«æã€ããšãã§ããã°çŽ æŽããããš
ããã¯ã次ã®ãããªããŒãžã«2ã€ã®ãã¡ã€ã«ãäœæããããšã§å®çŸã§ããŸãã
ããã«ããããããã·ã¯?amp=1
ã¯ãšãªãã©ã¡ãŒã¿ã«åºã¥ããŠampããã¥ã¡ã³ãã«è§£æ±ºã§ããŸãã
amp: 'hybrid'
ãšSSGæ©èœãåæã«æã€ããšãã§ããã°çŽ æŽããããš
ããã¯ã次ã®ãããªããŒãžã«2ã€ã®ãã¡ã€ã«ãäœæããããšã§å®çŸã§ããŸãã
- ïŒSSGïŒindex.html
- ïŒAMPïŒindex.amp.html
ããã«ããããããã·ã¯
?amp=1
ã¯ãšãªãã©ã¡ãŒã¿ã«åºã¥ããŠampããã¥ã¡ã³ãã«è§£æ±ºã§ããŸãã
ãŸãã«@Dacturneã§ãããããã¯ããã®ã¹ã¬ããã§ä»¥åã³ã¡ã³ãããŠããããã«ããããžã§ã¯ãã§ãã§ã«SSGã䜿çšãå§ããå¯äžã®æ¬ ç¹ã§ãã
ð€
@jansedlonç§ã¯ããªãã®è³ªåã«çããããã°æçš¿ãããŸããïŒ
ãã«ãæã«äžæãªã«ãŒãããã£ããããããã«ãããçš®ã®ã¯ã€ã«ãã«ãŒãã«ãŒãã䜿çšããæ¹æ³ãããã®ã ãããã ããšãã°CMSããŒã¿ããéçããŒãžãã¬ã³ããªã³ã°ã§ããã®ã¯çŽ æŽãããããšã§ããã誰ããæ°ããã¢ã€ãã ãè¿œå ããå Žåã¯ã©ããªããŸããïŒ ãã®ããã®éçããŒãžã¯ãããŸããã ãã®åé¡ã¯é·ãéç§ã®é ãæ©ãŸããŸããã
https://paqmind.com/en/blog/ssr-is-not-the-future
ïŒå€§ãããããããããã«ã¯æçš¿ããŸããïŒ
@ ivan-kleshninç°¡åã«èŠãŠã¿ãŸãããããšãŠããšããµã€ãã£ã³ã°ã«èŠããŸãïŒ ããªãã¯ç§ã«äœçŸæéãç¯çŽãããããããŸããïŒ ã©ããããããšãããããŸãããæ¬æ¥ã¯ãããã«è©³ããèŠãŠãããŸãã
https://github.com/zeit/next.js/issues/9524#issuecomment -582799948
@jansedlonã¯ãåã«è¿°ã¹ãããã«ã@ ivan-kleshninã®ããã°æçš¿ã§ã«ããŒãããŠããªããããã«é¢ããäœãã«åãçµãã§ããŸãã ããŸãããã°ãããã«ã€ããŠãã£ãšããã«å ±æã§ããããã«ãªãã§ãããã
@timneutkensãããŸã§ã®å€æŽã倧奜ãã§ãðå®å šãªéç+åœéåãæ¹å/ãµããŒãããèšç»ã¯ãããŸããïŒ
GatsbyããNext.jsãžã®tinacms.orgã®ç§»è¡ã§ã¯ãæ°ããgetStaticProps
/ getStaticPaths
APIã䜿çšããŠããŸãããããããŸã§ã®ãšãããã°ãããã§ãã
ç§ãã¡ãæ±ããŠããé害ã®1ã€ã¯ãRSSãã£ãŒãã®çæã§ãã åç §ããã³ã³ãã³ãã¯éçã«çæããããããçæ³çã«ã¯éçã«çæããŸãã çŸåšããããè¡ãæ¹æ³ãããããªãããã代ããã«ãã³ã³ãã³ããã¯ãšãªããŠå¿çã«XMLãæžã蟌ãããšã«ããããµãŒããŒåŽã§åŠçããŠããŸãã
HTML以å€ã®ã³ã³ãã³ãã¿ã€ãã®éççæããµããŒãããããšã«ã€ããŠã®è°è«ã¯ãããŸãããïŒ
åèãŸã§ã«ãzeitã§getStaticProps
䜿çšãéå§ãã --prod
ãã©ã°ã䜿çšããŠãªãªãŒã¹ããŸããããæ°ãããªãªãŒã¹ã§ã¯jsonãã¡ã€ã«ã®ãã£ãã·ã¥ãã¯ãªã¢ãããŠããŸããã§ããã æ¬çªãªãªãŒã¹ããšã€ãªã¢ã¹æ©èœã®äœ¿çšã«æ»ããšæ©èœãããã£ãã·ã¥ãã¯ãªã¢ãããŸããã
GatsbyããNext.jsãžã®tinacms.orgã®ç§»è¡ã§ã¯ãæ°ãã
getStaticProps
/getStaticPaths
APIã䜿çšããŠããŸãããããããŸã§ã®ãšãããã°ãããã§ããç§ãã¡ãæ±ããŠããé害ã®1ã€ã¯ãRSSãã£ãŒãã®çæã§ãã åç §ããã³ã³ãã³ãã¯éçã«çæããããããçæ³çã«ã¯éçã«çæããŸãã çŸåšããããè¡ãæ¹æ³ãããããªãããã代ããã«ãã³ã³ãã³ããã¯ãšãªããŠå¿çã«XMLãæžã蟌ãããšã«ããããµãŒããŒåŽã§åŠçããŠããŸãã
HTML以å€ã®ã³ã³ãã³ãã¿ã€ãã®éççæããµããŒãããããšã«ã€ããŠã®è°è«ã¯ãããŸãããïŒ
ç§ã¯èªåã§ãããèããŠããŸããããããŠç§ã¯ã¡ããã©ãããèŠã€ããŸããã ãããç§ã®ã¹ã¯ãªããã§ãïŒ
"scripts": {
"dev": " next",
"build": "yarn sitemap && next build",
"start": "next start",
"sitemap": "ts-node --project ./cli/tsconfig.spec.json ./cli/generateSitemap.ts"
},
next build
ãyarn sitemap
ãšåŒã°ããåã¯ãéçã«ãµã€ãããããçæããŸãã åãææ³ã䜿çšããŠãããšãã°getStaticProps
å¿
èŠã«ãªããã¹ãŠã®ããŒã¿ãjsonã«ãã£ãã·ã¥ããè€æ°ã®ããŒãžã§åå©çšã§ããŸãã
RFCãæŽæ°ãã getStaticPaths
åäœãå°ãå€æŽããŸããïŒä»ããpaths
ããŒãè¿ãå¿
èŠããããŸããããã¯ã props
ãè¿ãå¿
èŠãããgetStaticProps
åæ ããŠããŸããããã¯å€æŽã¯ãŸã Next.jsã«åæ ãããŠããŸããã
ãŸãã fallback
åäœïŒãã«ãæã«ãšã¯ã¹ããŒããããªãã£ãããŒãžã®ãªã³ããã³ãããã¯ã°ã©ãŠã³ãçæïŒã®èª¬æãè¿œå ããŸããã
RFCã«å¥ã®æŽæ°ãè¡ãã Loading
ç¶æ
ã«é¢ããã¯ã©ã€ã¢ã³ãããã²ãŒã·ã§ã³ã®å€æŽã«ã€ããŠã®èª¬æãè¿œå ããŸããã
èªã¿èŸŒã¿ç¶æ ãReactããã¯ãä»ããŠã¬ã³ããªã³ã°ãããŠãããã©ããããŠãŒã¶ãŒãç¥ãæ¹æ³ãè¿œå ãããå ŽåããããŸãð€
çŽ æŽããããã®ïŒ éçã«çæãããããŒãžããåäžã®JSONãã¡ã€ã«ïŒã³ãŒãåå²ã®ããã«ããŒã¿çšïŒã䜿çšããŠè€æ°ã®ã«ãŒãéã§ããŒã¿ãå ±æããæ¹æ³ã¯ãããŸããïŒ
ç§ã¯ææ°ã®canary
ãã«ãã«ã¶ã€ãããããã«æ°ããLoading
ç¶æ
ã«æ°ã¥ããŸããã 以åã¯ããã¥ãŒã¬ã€ã€ãŒãã¬ã³ããªã³ã°ãéå§ããåã«ãé©åãªããŒã¿ãæ¢ã«ååŸãããŠãããšå®å
šã«æ³å®ã§ããŠããŸããã 匷å¶éåæããŒãã¯ããããšã¯å€§ããç°ãªããŸãã æ°ããèªåçæãããSSRãšã³ããã€ã³ãã眮ãæãããã¹ãŠã®å®åãšã³ããã€ã³ãããªããã³ã°ããããšã¯æ¬åœã«æ¥œããã£ãã§ãããæ°ããLoading
ç¶æ
ãå«ãããã«ãã¹ãŠã®ããŒãžãåèšèšããäºå®ã¯ãããŸãã
ç§ã¯ãããé«éãªTTFBãå¿
èŠã§ããããšãç解ããŠããŸããå°æ¥çã«ã¯ããããç§ã®ã¢ããªã«ãšã£ãŠäŸ¿å©ãªãã®ã«ãªãå¯èœæ§ããããŸãã ããããäœãããšãå¯èœã«ãªããŸãLoading
ç¶æ
ã«äŒŒãªããã€ã³ãŸãã¯ãªããã¢ãŠãæ©èœã fallback: false
ã«ã€ããŠgetStaticPaths
ïŒ ãããããããŒãžã®export const enableLoadingState = false
ããŸãã¯ãµã€ãå
šäœã®next.config.js
ã§ãã
https://github.com/zeit/next.js/issues/9524#issuecomment -583962425
ç¹°ãè¿ãã«ãªããŸãããå®éšçãªæ©èœã䜿çšããŠãããçŸåšãã®åäœãå®éšããŠããããšãæãåºããŠãã ããã
ïŒå®éšçãªïŒSSG Webãµã€ããNowã«ãããã€ããŸããïŒããã©ã«ãã®ã»ããã¢ããã䜿çšïŒã æ£åžžã«åäœããŸããããµã€ããé²èŠ§ãããš[ãããã¯ãŒã¯]ã¿ãã«404ãšã©ãŒã衚瀺ãããŸãã 404ãšã©ãŒã¯ãã¹ãŠ_next/static/pages/[slug].js
æããŸãã
ããã¯å®éšäžã®äºæ³ãããåäœã§ããïŒ ãŸãã¯ãããã€ãã®èšå®ãå€æŽããå¿ èŠããããŸããïŒ
@joostmeijlesæ£ããhref
ãšas
ãnext/link
æäŸããŠããªãããã§ãã åçããŒãžã®å Žåã href
ã¯ããŒãžhref='/[slug]'
ã§ããå¿
èŠãããã as
ã¯URLã§ããå¿
èŠããããŸãas='/slug-1'
ãã«ãäžã«ã³ã³ãœãŒã«ã«3ã€ã®ãã°ã衚瀺ãããŸãããããã¯ãã°ã§ããïŒ
// Page is showing three logs despite static path only having 2 entries and output generating only two files as intended
export default function Page(props){
console.log("Page - should only show twice", props);
return <><h1>Page</h1></>
}
export async function unstable_getStaticProps(props) {
console.log("unstable_getStaticProps - should only show twice", props);
return {
props
};
}
export async function unstable_getStaticPaths() {
console.log("show once")
return {
paths: [
{ params: { year: "1901" } },
{ params: { year: "1902" } },
]
}
}
ããããRFCã®fallback
ã«åŸã£ãŠããã¯æåŸ
ãããŠããŸããã
ããããRFCã®
fallback
ã«åŸã£ãŠããã¯æåŸ ãããŠããŸããã
export async function unstable_getStaticPaths() {
console.log("show once")
return {
fallback: false,
paths: [
// This renders /blog/hello-world to HTML at build time
{ params: { year: "1901" } },
{ params: { year: "1902" } },
]
}
}
ãªããã¢ãŠãããããšããŸãããããã®ãšã©ãŒãçºçããŸãã
ãšã©ãŒïŒ/ [year]ã®unstable_getStaticPathsããè¿œå ã®ããŒãè¿ãããŸããïŒãã©ãŒã«ããã¯ïŒçŸåšèš±å¯ãããŠãããã£ãŒã«ãã¯
paths
ç¹°ãè¿ãã«ãªããŸãããå®éšçãªæ©èœã䜿çšããŠãããçŸåšåäœãå®éšããŠããããã¹ãŠãå®è£ ãããŠããããã§ã¯ãªãããšãæãåºããŠãã ããã
ãã®æ©èœgetStaticProps
ã¯ããŒãžã§ã®ã¿äœ¿çšã§ããŸããïŒ
ããšãã°ãã¢ããªã±ãŒã·ã§ã³ã®ã°ããŒãã«æ§æããã§ãããããªã©ãã¢ããª/ããã¥ã¡ã³ãã«ãšã£ãŠãèå³æ·±ãã§ããããïŒ
ç§ã¯ããããæåè£ã«ãå®è£ ãããããŸã§ã®çµæã«æºè¶³ããŠããŸããããããåŸç¶ã®ãã«ãããããéããããæ¹æ³ã¯ããã®ã§ããããã ããšãã°ãSSGã§çæãããããŒãžãå€æŽãããŠããªããã©ããã確èªããããããåçæããŸãããïŒ ïŒããããç§ããã®åžæç芳枬ïŒ
@timneutkens SSGããŒãžçšã®sitemap.xmlãžã§ãã¬ãŒã¿ãŒãè¿œå ããäºå®ã¯ãããŸããïŒ ä»ã®ãšãããéçããŒãžã«ã®ã¿å®è£ ããæ¹ãç°¡åã ãšæãã®ã§ãåçã«ãŒãã«ã€ããŠã¯è©±ããŠããŸããã
@timneutkens SSGããŒãžçšã®sitemap.xmlãžã§ãã¬ãŒã¿ãŒãè¿œå ããäºå®ã¯ãããŸããïŒ ä»ã®ãšãããéçããŒãžã«ã®ã¿å®è£ ããæ¹ãç°¡åã ãšæãã®ã§ãåçã«ãŒãã«ã€ããŠã¯è©±ããŠããŸããã
ãããããã¯çŽ æŽããããªãã·ã§ã³ã§ãããã çŸåšãSSRã䜿çšããŠèªåã§çæããŠããŸãã ïŒãã ããsitemap.xmlãã¡ã€ã«ã®èªã¿èŸŒã¿ã«ã¯æéãããããŸãïŒ
https://github.com/zeit/next.js/issues/9524#issuecomment -585293270
çéžåŸã«getStaticPropsã«åœ±é¿ãäžããä»ã®äœæ¥ããããããæåã¯ããŒãžã®ã¿ã
https://github.com/zeit/next.js/issues/9524#issuecomment -586957539
ã¯ãããã ãããã®RFCã®äžéšãšããŠã§ã¯ãããŸããã ãã®çéžåŸããã©ããŒã¢ããããããŸãã
@timneutkens NextãéçããŒãžãäœæãããã³ã«URIãé
åã«ããã·ã¥ããçµäºããããé
åãåXMLã¿ã°ã«ãããããçµåããŠäžå€®ã«æ¿å
¥ã§ãããããSSGããŒãžã®å®è£
ã¯ç°¡åã ãšæããŸãã <sitemapindex>
ã¿ã°ã®ã getStaticProps
ã¯ã excludeFromSitemap
ãšããååã®æ»ããªããžã§ã¯ãã«å¥ã®ããŒãæã€ããšãã§ãããããããã©ã«ãã§ã¯ããã¹ãŠã®ããŒãžãsitemap.xml
å«ãŸããŸããããªããã¢ãŠããããªãã·ã§ã³ããããŸãã
ãã®å Žåãéçºè
ã¯ã©ã®éçããŒãžããµã€ããããã«å
¥ãããã现ããå¶åŸ¡ã§ããŸãïŒããšãã°ãããŒãž[foo]
ã®getStaticPaths
é¢æ°ãfoo
ãã¹ãè¿ããå Žå'abc'
ãš'xyz'
ãããµã€ããããã«ã¯'abc'
ãã¡ã€ã«ã®ã¿ãå«ããå¿
èŠããããéçºè
ã¯excludeFromSitemap
ãtrue
ã«èšå®ã§ããŸãã getStaticProps
ã®ãã©ã¡ãŒã¿==='xyz'
true
å Žåã¯getStaticProps
ã
ãŸããSSRããã³éçããŒãžã®å Žåã getServerProps
ã getStaticPaths
ãããã³getStaticProps
ããã«ãããŒãžãã¡ã€ã«ããå®æ°ïŒã€ãŸãã export const excludeFromSitemap = true;
ïŒããšã¯ã¹ããŒãã§ããå¯èœæ§ããããŸãã getStaticProps
ããšã¯ã¹ããŒããããŸãã
SSGããŒãžã§ããšã¯ã¹ããŒããããexcludeFromSitemap
å®æ°ïŒããŒãžã®ããã©ã«ãïŒãããããã®ããŒãgetStaticProps
é¢æ°ããè¿ããããªããžã§ã¯ãïŒãã¹åºæïŒã«ãããå Žåããšã¯ã¹ããŒããããå€ã¯ããã©ã«ããšããŠæ©èœããå¿
èŠããããŸããã®ããŒãžå
ã®ãã¹ãŠã®ãã¹ã®å€ãšãã¹åºæã®excludeFromSitemap
ã¯ã getStaticProps
ãªããžã§ã¯ãã«ååšããå ŽåãããŒãžã®ããã©ã«ãããªãŒããŒã©ã€ãããå¿
èŠããããŸãïŒãããã£ãŠãããŒãžã¯export cosnt excludeFromSitemap = true
å®è¡ã§ããŸãïŒæ¬¡ã«ã excludeFromSitemap
ããŒãgetStaticProps
ããè¿ããããªããžã§ã¯ãã«å€false
è¿œå ããŠãç¹å®ã®ãã¹ãé€ããã¹ãŠã®ãã¹ããµã€ããããããé€å€ããŸãã
é åã«è¿œå ããããã®ã³ãŒãã¯æ¬¡ã®ããã«ãªããŸãïŒççå€è¡šãèšç®ããã«ã«ããŒå³ã䜿çšããŠæå°ããŒã«åŒãååŸããŸããïŒã
//...somewhere else
const validExcludeFromSitemapTypes = ['boolean','undefined'];
//...for each path
const isSSG = !!getStaticPropsReturnedObj && typeof getStaticPropsReturnedObj === "object";
if(
validExcludeFromSitemapTypes.indexOf(typeof pageExports.excludeFromSitemap)<0 ||
(isSSG && validExcludeFromSitemapTypes.indexOf(typeof getStaticPropsReturnedObj.excludeFromSitemap)<0)
) {
throw new Error("'excludeFromSitemap' can either be ommited (undefined) or be a boolean");
}
const defaultExcludedValue = !!pageExports.excludeFromSitemap;
const hasSpecificExcluded = isSSG && typeof getStaticPropsReturnedObj.excludeFromSitemap !== "undefined";
const specificExcludedValue = isSSG ? !!getStaticPropsReturnedObj.excludeFromSitemap : false;
if(!specificExcludedValue && (!defaultExcludedValue || hasSpecificExcluded))
sitemapURIs.push(correctlyEncodedURI);
é
åããµã€ããããã«å€æããã®ã¯ããããè¡ãã®ãšåããããç°¡åã§ãïŒé
åå
ã®URIããã§ã«ãšã³ã³ãŒãããã !excludeFromSitemap
ãã£ã«ã¿ãªã³ã°ãããŠãããšä»®å®ããŸãïŒã
function createSitemap(sitemapURIs: string[]): string {
return `<sitemapindex>${sitemapURIs.map(u=>`<sitemap><loc>u/loc></sitemap>`).join('')}</sitemapindex>`;
}
Next.JSã®äœ¿åœã®äžéšã¯ããŠãŒã¶ãŒã«100 SEOã¹ã³ã¢ãäžããããšã§ããã sitemap.xml
ãæã£ãŠãããšéåžžã«åœ¹ç«ã€ããããã®æ©èœã¯Next.JSã«ããŸãåãŸããšæããŸãã ïŒ robots.txt
ã¯ããµã€ããããé
åã«ãã¹ãè¿œå ããŠããã®ãã¹ãèš±å¯ãããŠããªãããŒãžã®å¥ã®é
åã«è¿œå ããæ¡ä»¶ã«else
ãè¿œå ããŠçæãããå¯èœæ§ããããŸãïŒ
çŸåšã®ãªãªãŒã¹ããŒãžã§ã³ã§ã¯ã䜿çšããŠããå Žåunstable_getStaticPaths
ãšäžç·ã«unstable_getStaticProps
äžã«äœãã§ããæ©èœã«æ©èœããããªããäœãããšãã§ããªãAPIåŒã³åºã/api/
ã
ãµãŒããŒãå®è¡ãããŠããªãããã察å¿ããèŠæ±ãè¡ã£ãŠéçââå°éå
·ããã®æ¹æ³ã§çæããããšã¯ã§ããŸããã
ãã¹é¢æ°ãæäŸããå¿
èŠã¯ãããŸããïŒããã«ãããåºæ¬çã«ãã®SSRã«ãã£ãã·ã¥ãäœæãããŸãããããã§ã䟿å©ã§ãïŒïŒããŸãã¯SSGã§ã¯ãªãSSRã«äŸåããå¿
èŠããããŸãã
å€åããã¯ãã®æ©èœã®è¯ãè¿œå ã«ãªãã§ããããïŒ ããã§ã®æåã®æ¹æ³ãããããªãã®ã§ãã©ããå¥ã®å Žæã§ææ¡ãèªã¿ãŸãããããã¯ãSSRãš/api
ã«ãŒãã䜿çšããŠhttpãªã¯ãšã¹ããã·ã§ãŒãã«ããããããšãææ¡ãããã®ã§ãããã§ã䟿å©ã§ãã
ããããããã¯ãã¡ããããã«ãç°å¢ã§ã³ãŒããå®è¡ããããšãæå³ããä»ã®ãµãŒãã¹ãdbåŒã³åºããªã©ãåŒã³åºããŸãã ãããå®è£ ãããšãã«ãããæ確ã«ããå¿ èŠããããŸããããã®æ©èœã®ã¯ãŒã«ãªè¿œå ã«ãªããŸãã
@reckterãããç§ã¯èªåãšåããããªããšãããã éçã«çæãããŠããéãåå¥ã®ããŒãžèŠæ±ããšã«ããŒã¿ããŒã¹ã«æ¥ç¶ããå¿ èŠããããŸããã ãšãŠãå¥åŠã«æããŸãã...
ãããæçµçãªãŠãŒã¹ã±ãŒã¹ã§ã¯ãªãããšãé¡ã£ãŠããŸã
next.configãªã©ããã»ããã¢ããã§ããããçš®ã®åæåã¹ã¯ãªããããããšäŸ¿å©ã§ã...
@reckter HTTPãªã¯ãšã¹ããSSG / SSRããAPIã«ãŒãã«ã·ã§ãŒãã«ããããæ¹æ³ã¯ãšãŠãè¯ãã§ãããïŒ ãããã®ã·ããªãªã®ããããã§èªåèªèº«ã«ãããã¯ãŒã¯èŠæ±ãè¡ãã®ã¯å¥åŠã«æããŸãã
ãšã«ãããSSGäžã«APIã«ãŒãã«ã¢ã¯ã»ã¹ããããã®å¯èœãªè§£æ±ºçã¯ãéçããŒãžãã³ã³ãã€ã«ããåã«ãããŒã«ã«ãµãŒããŒã«/api
ã«ãŒãã®ã¿ãå®è¡ãããããšã§ãã ãããã£ãŠããã«ãæé ã¯æ¬¡ã®ããã«ãªããŸãã
/api
ã«ãŒãã®ã¿ãæäŸãããµãŒããŒïŒãapiã³ã³ãã€ã«ãµãŒããŒããªã©ãšåŒã°ããããšããããŸãïŒãèµ·åããŸãunstable_getStaticPaths
å®è¡ããŸãunstable_getStaticProps
å®è¡ããŸã@reckterã¯åºæ¬çã«ãAPIã«ãŒããåŒã³åºãå¿ èŠã¯ãªããå®è£ ããé¢æ°ãçŽæ¥åŒã³åºãããšãã§ããŸããããã«ãããhttpã®åå ãè¶ ããå€ãã®ãªãŒããŒããããåé¿ãããŸãã
åºæ¬çã«ãçŸåšæ¬¡ã®ãããªAPIã«ãŒããããå ŽåïŒ
import myDb from 'mydatabaseprovider'
const db = myDb()
export default async (req, res) => {
cont myData = await db.query('posts')
res.json(myData)
}
次ã®ããã«å€æŽããŸãã
import myDb from 'mydatabaseprovider'
const db = myDb()
export async function getData() {
const myData = await db.query('posts')
return myData
}
export default (req, res) => {
const myData = await getData()
res.json(myData)
}
ãããŠããªãã®ããŒãžã§ïŒ
import {getData} from './api/myfunction'
export async function getStaticProps() {
const myData = await getData()
return {
props: {
myData
}
}
}
GraphQLAPIã«å¯ŸããŠåãããšãè¡ãã®ã¯é£ããã§ãããã ãŸããã»ãšãã©ã®RESTã§ãåæ§ã§ãã
APIåŒã³åºãïŒ= DBããã®ãã§ããïŒäžè¬ïŒ
ã»ãšãã©ã®å ŽåãAPIã¬ã€ã€ãŒã«ã¯ããã£ãŒã«ãã®ååå€æŽãããŒã¿ã®åãã©ãŒããããªã©ã®ããžãã¹ããžãã¯ããããŸãã
pages/api
åŒã³åºããçŠæ¢ããçç±ããããšç¢ºä¿¡ããŠããŸã...ããããå®éã®APIã®ãã€ãã¹ã¯ç°¡åã§ãå®äŸ¡ã§ããããŸããã ãŸããæ°ããªç§ã®äœè£ãããã°ãè¿œå ã®ã³ãŒã/è€é床IMOã®æéãäžåãããšã¯ãããŸããã
ãŸããä»»æã®APIãžã®ãªã¯ãšã¹ããèš±å¯ãããã®ã¯å¥åŠã«æããŸãã ããªãèªèº«ãé€ããŠð€·ââ
unstable_getStaticPaths
ãšãããŒãžããªããŒããããããšãã°reduxã§çŸåšã®ç¶æ
ã倱ãããŸãã ãã®åäœã¯å°æ¥å€æŽãããŸããïŒ
ç·šéïŒãã®åäœã¯ããªã³ã¯ãŸãã¯ã«ãŒã¿ãŒã§as
ãªãã·ã§ã³ã䜿çšããããšã§åé¿ã§ããããã§ã
<Link
href='/item/[key]'
as={`/item/${itemName}`}
>
router.push(
'/item/[key]',
`/item/${itemName}`
);
@meesvandongenããã¯ãã€ãããã ã£ãã <Link>
ãç¡å¹ãªå Žåã¯ãåºæ¬çã«<a>
ãšããŠæ©èœããããã¯ãšã³ãéšåã«ç§»åããŸãã [key]
ãããªåçãã©ã°ã¡ã³ãã¯ã察å¿ããå€ãšãã¢ã«ããå¿
èŠããããŸãã
@reaktivo
pages/[lang]/blog/[id].js
->getStaticPaths
ãéçã«ã¬ã³ããªã³ã°ãããã¹ãŠã®URLãæäŸããŸãã
https://github.com/zeit/next.js/issues/9524#issuecomment -562625858
ãã®å Žåã«ã¯è¿œå ããå¿
èŠããããŸãgetStaticPaths
ãã getStaticProps
index.jsãé€ããã¹ãŠã®ããŒãžã®ããã®æ©èœã
mdxããŒãžãããã€ãããå Žåããããžã§ã¯ãã®ä¿å®ã¯ããå°é£ã«ãªããŸã
éçgetStaticPaths
getStaticProps
ã¡ãœãããžã®å€æŽãŸãã¯äºææ§ãæ€èšããŠãã ããã https://github.com/zeit/next.js/issues/9524#issuecomment -558617056
ãã®å ŽåãããŒãžã¯é«éé¢æ°ãŸãã¯é«éã³ã³ããŒãã³ãïŒHOCïŒã§ã©ããã§ããŸãã
ãã®ããã«ããŠãã³ãŒãã¯typesscriptã«ãšã£ãŠããä¿å®ããããããã䟿å©ã«ãªããŸãã
ããªãŒã·ã§ã€ã¯ãšãã€ãããã¯ã ãªããšããé çã®çš®ã®ãã¬ãŒããªããð
9.2.3-canary.13
ã䜿çšããŠãgetStaticPathsã§fallback: false
ã次ã®ããã«äœ¿çšããŠã¿ãŸããã
return {
fallback: false,
paths: slugs.map(slug => ({params: {slug: slug}}))
}
ãã ãã次ã®ãšã©ãŒã§å€±æããŸãã
Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }
9.2.3-canary.13
ã䜿çšããŠãgetStaticPathsã§fallback: false
ã次ã®ããã«äœ¿çšããŠã¿ãŸãããreturn { fallback: false, paths: slugs.map(slug => ({params: {slug: slug}})) }
ãã ãã次ã®ãšã©ãŒã§å€±æããŸãã
Error: Extra keys returned from unstable_getStaticPaths in /blog/[slug] (fallback) Expected: { paths: [] }
ãããã1ã¬ãã«é«ãããå¿ èŠããããšæãã®ã§ãmapã¯çŸåšæã£ãŠãããªããžã§ã¯ããè¿ããŸãããåºæã®ã¹ã©ãã°ããããŸãã ãã¹ã«ãããã³ã°ãã代ããã«ã
nextjsã®ããŒãžã§ã³ã¯ãŸã æŽæ°ããŠããŸããããåæ§ã®ã¯ãã§ãã
return data.map(item => {
return {
params: {
slug: item.slug,
},
}
})
@jorngeorgããã¯ãªãŒãã³PRã§ãïŒ https ïŒ
çŽ æŽãããè²¢ç®ïŒ éçã¬ã³ããªã³ã°ããã»ã¹ãæ¬åœã«æ¹åãããŸãã
åçã«ãŒãã§ã¯ã getStaticProps
åŒã³åºããªããŠãããã©ãŒã«ããã¯ããçæãããããšãããã¥ã¡ã³ãã«è¿œå ããããšããå§ãããŸããã€ãŸããå°éå
·ã空ã®å Žåãèæ
®ããŠã³ã³ããŒãã³ããã³ãŒãã£ã³ã°ããå¿
èŠããããŸãã
ãŸãã¯ããã©ãŒã«ããã¯ãäœæãããšãã«ã³ã³ããã¹ããªãã§getStaticProps
ãåŒã³åºãããã«åäœãå€æŽããããšãã§ããŸãã ããã¯ã next export
çŸåšã©ã®ããã«æ©èœããŠããããšäžèŽããŸãïŒããšãã°ã /p/[id].js
ã¯ãã³ã³ããã¹ããªãã§getInitialProps
ãå®è¡ããããšã«ããã /p/[id].html
ãšã¯ã¹ããŒããããŸãïŒã
getStaticProps
-next build
æç¹ã§éççæïŒSSGïŒã«ãªããã€ã³ããŸããgetServerProps
-ãªã³ããã³ãã§ã¬ã³ããªã³ã°ãããµãŒããŒåŽã¬ã³ããªã³ã°ïŒSSRïŒã«ãªããã€ã³ããŸãã
getServerPropsã®ååãgetServerSidePropsã«å€æŽããŸãã
åçã«ãŒãã§ã¯ã
getStaticProps
åŒã³åºããªããŠãããã©ãŒã«ããã¯ããçæãããããšãããã¥ã¡ã³ãã«è¿œå ããããšããå§ãããŸããã€ãŸããå°éå ·ã空ã®å Žåãèæ ®ããŠã³ã³ããŒãã³ããã³ãŒãã£ã³ã°ããå¿ èŠããããŸãã
èšåããã®ã«è¯ãç¹ã§ãïŒ ç§ã¯ãããéããã®ã§ãããã€ãã®ãã«ã/ãããã€ã¡ã³ããšã©ãŒããããŸããã
å€æŽãåæ ããããã«RFCãæŽæ°ããŸãã
@timneutkens
- åããã¹ãžã®åŸç¶ã®ãªã¯ãšã¹ãã¯ãçæãããããŒãžãæäŸããŸã
ããã¯ãNext.jsãçæãããããŒãžããã£ãã·ã¥ããããšãæå³ãããšæããŸããïŒ ããã¯ã¡ã¢ãªå ãã£ãã·ã¥ã§ããïŒ ãã®ãã£ãã·ã¥ã¯å¶éã«ãã£ãŠå¶éãããŠããŸããããããšãã¡ã¢ãªãªãŒã¯ãçºçããå¯èœæ§ããããŸããïŒ
next start
ã䜿çšãããšãçŸåšã®ãã£ãã·ã¥ã®äŸãšåæ§ã®lru-cacheã䜿çšãããŸããçŸåšãããã©ã«ãã®å¶éã¯50MBã§ããåŸã§èšå®ã§ããããã«ãªãå¯èœæ§ããããŸãïŒ https ïŒ
ZEITã§ãã¹ãããå Žåçæãšãã£ãã·ã¥ã¯CDN /ãããã·ã§è¡ããããããåäœãå°ãç°ãªããã¡ã¢ãªãªãŒã¯ãlruå¶éãè¶ ããŠãããã©ãããå¿é ããå¿ èŠã¯ãããŸããã
ðããããŸãããåççãªããã§ãã ããã¯å€ããå°ãªãããç§ãè³¢æãªããã©ã«ãã®æ¯ãèããšããŠèããŠãããã®ã§ãã
getStaticProps
-next build
æç¹ã§éççæïŒSSGïŒã«ãªããã€ã³ããŸããgetServerProps
-ãªã³ããã³ãã§ã¬ã³ããªã³ã°ãããµãŒããŒåŽã¬ã³ããªã³ã°ïŒSSRïŒã«ãªããã€ã³ããŸãã10722
getServerPropsã®ååãgetServerSidePropsã«å€æŽããŸãã
ãªãååãå€æŽããã®ã§ããïŒ IMHO getServerPropsã¯ååã«æ£ç¢ºã§ãå ¥åããã®ã«çãã®ã§ãSideãè¿œå ããã®ã¯åé·ã ãšæããŸãã
getStaticPathsã¡ãœããã«å€æŽãå ããããŠãããã©ããçåã«æããŸãããïŒ ç§ã®åçããŒãžã¯éçããŒãžãšããŠçæãããªããªããŸãããã©ã ãé¢æ°ãšããŠãšã¯ã¹ããŒããããããã«ãªããŸãããïŒ
ããŒãžãæåã«ã©ã ããšããŠã¬ã³ããªã³ã°ãããç¹å®ã®ããŒãžã«ã¢ã¯ã»ã¹ããåŸã«ã®ã¿ããŒãžãéçããŒãžã«çæããããšããããã©ã«ãã®åäœãæ£ããå Žåãç§ã¯æ£ããã§ããïŒ ïŒãã©ãŒã«ããã¯ã§è¿°ã¹ãããã«ïŒ
@erhankaradeniz getStaticPaths
å€æŽãå ããããŠããªããããããŒãžãã©ã ãã«ãªããŸãã ããã¯ã䜿çšäžã®ãšã©ãŒã§ããå¯èœæ§ããããŸãã
åé¡ãç¹å®ã§ããããã«ãã³ãŒãã衚瀺ããŠããã ããŸããïŒ
@Timerã¯ä»ã®ãšãã[email protected]ã«æ»ã£ãŠããããã¹ã§æ©èœããªãçç±ãããããŸã§ãåŒãç¶ãparamsã䜿çšã§ããŸãã
ããã¯ç§ãçŸåšç§ã®ãã¹ãçæããæ¹æ³ã§ãïŒ
return cityData.map(city => {
return {
params: {
country: city.countrySlug,
city: city.slug,
},
}
})
ãããŠä»ã®ããŒãžã§ç§ã¯ããŸãïŒ
return cityData.map(city => {
return {
params: {
country: city.countrySlug,
city: city.slug,
},
}
})
ãã¹ã䜿çšããŠãæ°ããã«ããªã¢ãªãªãŒã¹ã«å€æããããšãã§ããŸããã§ããã console.logsã¯getStaticPath
å
ã§ããããªã¬ãŒãããªãã®ã§ãç§ã¯äœãééã£ãããšãããŠããã«éããããŸãã
ãã¹ãããããã¹ã®äºåã¬ã³ããªã³ã°ãšSSGã«åé¡ããããŸãã
// pages/[lang]/[...slugs].js
export async function getStaticPaths() {
let knex = await import("knex/client").then(m => m.default)
let pages = await knex("page").select(["lang", "url"])
return {
fallback: true,
paths: pages.map(page => {
return {
params: {
lang: page.lang,
slugs: page.url == "/" ? [] : page.url.slice(1).split("/"),
}
}
}),
}
}
ã«ã€ãªãã
Error occurred prerendering page "/en/". Read more: https://err.sh/next.js/prerender-error:
Error: The provided export path '/en/' doesn't match the '/[lang]/[...slugs]' page.
ããŒã ããŒãžçšã äœããã®çç±ã§NextJSãäžèŽããŸãã
{lang: "en", slugs: []}
ã«
/[lang]/[...slugs]
{lang: "en", slugs: ["/"]}
ãæäŸãããšããã«ããããŸãããURLãééã£ãŠããŸãã
â â /[lang]/[...slugs] 875 B 204 kB
â â /en/credits
â â /en/%2F
ã¡ãªã¿ã«ã getServerSideProps
ã¯ãåæ§ã®èšå®ã§æ£åžžã«æ©èœããŸãã
å®éšçãªããšã¯ç¥ã£ãŠããŸããããã®ã¹ã¬ããã¯ãã£ãŒãããã¯ãæäŸããããã®ãã®ã§ãããïŒ
pages/[lang]/[...slugs].js
ãšäžèŽãã/en/abcdef
ãªã/en
䜿çšãããšãçŸåšäœæããå¿
èŠãããããã®ããã«ã pages/[lang]/index.js
ã
ãã®ããã«éãããŠããæ©èœãªã¯ãšã¹ãããããŸãïŒ //github.com/zeit/next.js/issues/10488
ãŸã第äžã«ãããã¯çŽ æŽãããã§ãã ç§ã¯Next.jsã«ãã®ãããªãã®ãããããšãæãã§ããã®ã§ãæçµçã«Gatsby.jsããé¢ããŠããã€ããªããã¢ããªïŒéç+åçïŒã䜿çšã§ããããã«ãªããŸããã
ðã«ããªã¢ãè©ŠããŠã¿ãŸããããååçŒãããŠã®è€éãªã¢ããªããŒãžã§ã³ã¯åé¡ãªãåäœããŸããã ç§ã¯ããã§ãã¹ãŠã®ã³ã¡ã³ããèªãã ããã§ã¯ãªãããšãåçœããŸãããããªãŒã·ã§ã€ã¯ããŸã å®è£ ãããŠãããã©ããã¯ããããŸããã
ð€ getStaticPaths
ã¯ãSSGåäœã®éçãã¹ãå®çŸ©ããŠããsetStaticPaths
ããã«æããŸãã ããããã®ã¯å°ãæžæããŸããã
ð§ãã«ãã«ããŽãªãèšå®ããããšã§ãã«ãæéãæ¹åã§ãããã©ããçåã«æããŸããïŒ ããã«ããã»ããã¢ãããè€éã«ãªãããšã¯ããã£ãŠããŸãããããã ãã®äŸ¡å€ã¯ãããŸãã 説æãããŠãã ããïŒ
ç§ãã¡ã®ãããªãã®ãsetBuildCategory
ãšã»ããã«blog
ãŸãã¯pages
ãŸãã¯èª°ããæãã§ãããã®ã¯äœã§ã2020-content
ã 次ã«ãSSGãã«ããŒã¯ãå€æŽãããããŒãžã®ã«ããŽãªãŒãæ¢ãããã£ãã·ã¥ãšæ°ããã¬ã³ããªã³ã°ã®çµã¿åãããããã®ã«ããŽãªãŒãåæ§ç¯ããããšããã ãã§ãã ãã®ãããªãã®ã¯ãSSGãé«éåãã倧å¹
ã«å€æŽãããåŸåã¯ãªããã®ã®ãã¢ãŒã«ã€ãã§ããªãããå€æŽãããå¯èœæ§ããããã®ã®ãã«ãæéã倧å¹
ã«ççž®ããã®ã«åœ¹ç«ã¡ãŸãã
ãããçã«ããªã£ãŠããå Žå; é»è©±ã«é£ã³ä¹ã£ãŠãããã«ã€ããŠãã£ããã§ããŠããããã§ãã
ã«ã¹ã¿ã ãµãŒããŒã®å®è£
ã§getServerSideProps
ãåŠçããæ¹æ³ã¯ïŒ
if (pathname === '/a') {
app.render(req, res, '/b', query)
}
äžèšã®äŸã§ã¯ã /a
ã«ã¢ã¯ã»ã¹ãããšãããŒãžãpages/b.js
ãŸãã ãã ããã¯ã©ã€ã¢ã³ãåŽã®/a
ãžã®ãªãã€ã¬ã¯ãã¯ã a.json
ãã¡ã€ã«ãããŠã³ããŒãããããšããŸããããã®å Žåã¯ååšããŸããã
ç°ãªãJSONãã¡ã€ã«ãã¬ã³ããªã³ã°ããããã®/_next/data/{BUILD_ID}/{PAGE}.json
ãžã®ãªã¯ãšã¹ãã«å¯ŸããŠåæ§ã®æ¡ä»¶ãããã¯ãã§ããïŒ
getStaticPathsã§fallback: true
ã䜿çšããå Žåãreqãªããžã§ã¯ããååŸããã«ã¯ã©ãããã°ããã§ããïŒ çŸåšãç§ã«ã¯ã§ããªãããã§ãã ç§ããããå¿
èŠãšããçç±ã¯ãã«ãŒããèªèšŒããããã«ãã©ãŠã¶ããããã€ãã®ã¯ãããŒãååŸããããã§ã
@tylermcrobertãªã¯ãšã¹ãããŸã£ãããªããšãã«ãCookieã
å®éã®èšªåè
ã®èŠæ±ã«äŸåããããã¯ãšã³ããæã€ã«ãŒãã¯ããéçãããã³ãåçãã®å®çŸ©ã«ãã£ãŠéçã«ããããšã¯ã§ããŸããã éçãšèªèšŒãçµã¿åãããããšãã§ããªãããšã¯èšããŸã§ããããŸãã...ããã¯ãèªèšŒéšåãããŒãžã§ã¯ãªãAPIãšã¯ã©ã€ã¢ã³ãã³ãŒãã«å±ããã ãã§ãã
ã«ã¹ã¿ã ãµãŒããŒã®å®è£ ã§
getServerSideProps
ãåŠçããæ¹æ³ã¯ïŒif (pathname === '/a') { app.render(req, res, '/b', query) }
äžèšã®äŸã§ã¯ã
/a
ã«ã¢ã¯ã»ã¹ãããšãããŒãžãpages/b.js
ãŸãã ãã ããã¯ã©ã€ã¢ã³ãåŽã®/a
ãžã®ãªãã€ã¬ã¯ãã¯ãa.json
ãã¡ã€ã«ãããŠã³ããŒãããããšããŸããããã®å Žåã¯ååšããŸãããç°ãªãJSONãã¡ã€ã«ãã¬ã³ããªã³ã°ããããã®
/_next/data/{BUILD_ID}/{PAGE}.json
ãžã®ãªã¯ãšã¹ãã«å¯ŸããŠåæ§ã®æ¡ä»¶ãããã¯ãã§ããïŒ
Next.jsã¯åçã«ãŒããã©ã¡ãŒã¿ããµããŒãããŠãããããã«ã¹ã¿ã ãµãŒããŒã§ã®åãããã³ã°ãå¿ èŠã«ãªãããšã¯ã»ãšãã©ãããŸããïŒ https ïŒ//nextjs.org/docs/routing/dynamic-routes
æŠèª¬ããã¢ãããŒãã¯<Link>
ã§ã¯æ©èœããªãããïŒããŒãžå
šäœã®é·ç§»ãçºçããŸãïŒãgetServerSidePropsã¯ãã§ã«æ©èœããŸãã
@tylermcrobertãªã¯ãšã¹ãããŸã£ãããªããšãã«ãCookieã
å®éã®èšªåè ã®èŠæ±ã«äŸåããããã¯ãšã³ããæã€ã«ãŒãã¯ããéçãããã³ãåçãã®å®çŸ©ã«ãã£ãŠéçã«ããããšã¯ã§ããŸããã éçãšèªèšŒãçµã¿åãããããšãã§ããªãããšã¯èšããŸã§ããããŸãã...ããã¯ãèªèšŒéšåãããŒãžã§ã¯ãªãAPIãšã¯ã©ã€ã¢ã³ãã³ãŒãã«å±ããã ãã§ãã
ãã®å Žåã®ãã©ãŒã«ããã¯ãªãã·ã§ã³ã誀解ããŠãããããããŸããã ããªããèšã£ãŠããããšã¯ããã«ãæã®ã³ã³ããã¹ãã§ã¯å®å šã«çã«ããªã£ãŠããŸãã
äºåå®çŸ©ãããã«ãŒãããªãå Žåã®fallback: true
ã§ã¯ãããŸãããïŒ ãã®å Žåããã©ãŠã¶ãããã©ãŒã«ããã¯ã«å°éããŸããã
@tylermcrobertã¯ãfallback: true
ã±ãŒã¹ã«ã¯ãªã¯ãšã¹ãããããŸãããAPIã¯ãæå°å
¬åæ¯ãã«ãã£ãŠçµ±åããå¿
èŠããããŸãã ãã¹ãŠã1ã€ã®æœèšã®ã»ããã§æ§ç¯ããããã®åŸããŸã£ããç°ãªãæœèšã®ã»ããã§æ®µéçã«æŽæ°ããã皌åäžã®ã·ã¹ãã ãæ³åããããšã¯ã§ããŸããã æ¯æŽããã®ã¯å€§æšäºã«ãªããŸãã
ãããã®ã€ã³ã¯ãªã¡ã³ã¿ã«ãã«ãããã«ãéã§ãã£ãã·ã¥ããããšããç¹ãèŠéããŠãããšæããŸãã ãããã£ãŠãæåã®èšªåè ã®åœ¹å²ã¯ãçµæãšããŠçãããã¹ãŠã®ãŠãŒã¶ãŒã®ãã«ãçµæã«åœ±é¿ãäžããŸãã æªãèãã®ããã«èãããŸãã
@ ivan-kleshninç§ã¯ç解ããŠããã確ãã«åæããŸãã ç§ãå°ããçç±ã¯ãç§ã®ç¹å®ã®ãŠãŒã¹ã±ãŒã¹ã®ããã§ãã
ãã¬ãã¥ãŒæ©èœãå¯èœã«ãããããã¬ã¹CMSã䜿çšããŠããã®ã§ããã¬ãã¥ãŒããå¿ èŠã®ããããŒãžã¯ãã«ãæã«å«ãŸããŸããïŒãã¬ãã¥ãŒããããšã³ããªã¯ãã®æç¹ã§ã¯ååšããªãããïŒã ããã¯ãã©ãŒã«ããã¯ãªãã·ã§ã³ãç»å Žããã±ãŒã¹ã ãšæããŸããã
ãã®ãã¬ãã¥ãŒã«ã¢ã¯ã»ã¹ããã«ã¯ãCookieãä»ããŠæäŸãããAPIãã¬ãã¥ãŒåç §ã«ã¢ã¯ã»ã¹ããå¿ èŠããããŸãã
ããã¯ã useStaticProps
å®å
šã«å»æ£ããå¿
èŠãããå Žåã§ããïŒ ããã¥ã¡ã³ãããã¬ãã¥ãŒã§ããªããããéçãã«ãã®ã¡ãªããã倱ããããããŸããã
gatsbyã®ãããªãã®ã«å¯Ÿãããã®RFCã®é åã¯ãéçãµã€ãçæã«ããããã€ããªããå¶åŸ¡ããæäŸãããããã¬ã¹CMSã§ã®äœæ¥ã軜æžããããšã§ãã
ãã¬ãã¥ãŒæ©èœãå¯èœã«ãããããã¬ã¹CMSã䜿çšããŠããã®ã§ããã¬ãã¥ãŒããå¿ èŠã®ããããŒãžã¯ãã«ãæã«å«ãŸããŸããïŒãã¬ãã¥ãŒããããšã³ããªã¯ãã®æç¹ã§ã¯ååšããªãããïŒã ããã¯ãã©ãŒã«ããã¯ãªãã·ã§ã³ãç»å Žããã±ãŒã¹ã ãšæããŸããã
ãã°ãããåŸ ã¡ãã ããðµ
ãããã£ãŠããããæ£ããããšãç解ããŠããã°ãããšãã°ãŠãŒã¶ãŒãç»é²ããå ŽåïŒæ°ããããŒãž/ãŠãŒã¶ãŒã§ããããéçããŒãžã¯çæãããŸããïŒããã©ãŒã«ããã¯trueã䜿çšã§ããŸããããããã¡ã€ã«ã«ã¢ã¯ã»ã¹ãããšèªåçã«çæãããŸããïŒ
Erhan Karadeniz
http://www.erhankaradeniz.com
2020幎3æ4æ¥ã®20:25ã«ãTimNeutkensã®[email protected]ã¯æ¬¡ã®ããã«æžããŠããŸãã
ã
ãã¬ãã¥ãŒæ©èœãå¯èœã«ãããããã¬ã¹CMSã䜿çšããŠããã®ã§ããã¬ãã¥ãŒããå¿ èŠã®ããããŒãžã¯ãã«ãæã«å«ãŸããŸããïŒãã¬ãã¥ãŒããããšã³ããªã¯ãã®æç¹ã§ã¯ååšããªãããïŒã ããã¯ãã©ãŒã«ããã¯ãªãã·ã§ã³ãç»å Žããã±ãŒã¹ã ãšæããŸããããã°ãããåŸ ã¡ãã ããðµ
â
ããªããèšåãããã®ã§ããªãã¯ãããåãåã£ãŠããŸãã
ãã®ã¡ãŒã«ã«çŽæ¥è¿ä¿¡ããããGitHubã§è¡šç€ºããããç»é²ã解é€ããŠãã ããã
ãã®ã¯ã©ã€ã¢ã³ãåŽããã§ãããããã®ã§ããŠãŒã¶ãŒããŒã¿ã¯æªãäŸã§ãã ãã©ãŒã«ããã¯ã¯ããã«ãæã«çæãããŠããªãããŒãžãéçã«çæãããªã³ããã³ãçšã«ãããŸãã ããšãã°ããã«ãæã«äžäœ100ã®ããã°æçš¿ãçæãããã©ãã£ãã¯ã®å°ãªãä»ã®ããã°æçš¿ãçæããããªãå ŽåããããŸãã
ããã¥ã¡ã³ãã¯ãŸããªãäžéžããŸãã
ãããç§ãæå³ããã®ã¯ãã¬ãŒã¹ãã«ããŒããŒãžã§ããã確ãã«ã¯ã©ã€ã¢ã³ãåŽã§ãŠãŒã¶ãŒããŒã¿ããã§ããããŸãã
@timneutkenséçã«çæãããç¹å®ã®ããŒãžãåé€ãŸãã¯åæ§ç¯ããæ¹æ³ã¯ãããŸããïŒ
ããïŒïŒïŒ æé©ãªã¢ããªã±ãŒã·ã§ã³ã®ããã«èãããŸãã ç§ã¯ReactãšNextã®äž¡æ¹ã倧奜ãã§ã!!! ãã¹ãŠããšãŠããšã¬ã¬ã³ãã§ã·ã³ãã«ã«äœ¿ããããã«ãªããŸãã!! ãããããã®äŸã«ã¯æŠå¿µããã°ãå«ãŸããŠããŸãã ãããã¬ã¹CMSã«ã¯ãšãªãå®è¡ããéçã¢ã€ãã ãšããŠã®ãšã¯ã¹ããŒããšããŠããŒãž/æçš¿ããšã«ãã§ãããå®è¡ããå Žåã®å®è£ äŸã確èªããããšæããŸãã
//éææ¥ãè¿ãã®ã§ã也æ¯!!!
@timneutkensããã¯ãšããµã€ãã£ã³ã°ã§ãð
ç§ãã¡ãé »ç¹ã«ãããããã·ããªãªã®1ã€ã§ãããåçã«ãŒããŸãã¯ã«ãŒãå ã®ãããžã§ã¯ãã®çæãé€ããŠãnext.jsãŸãã¯gatsbyã䜿çšããå®å šãªãœãªã¥ãŒã·ã§ã³ã¯ãŸã ãããŸããã
æŽå²çãªçç±ãããäŸ¡æ Œãé貚ããµããŒãé»è©±çªå·ãèšèªã»ã¬ã¯ã¿ãŒãé€ããŠãåã/æ£ç¢ºãªããŒãžãæäŸããè€æ°ã®ãã¡ã€ã³ãåŠçããå¿ èŠããããŸãïŒãããå€æŽããæ欲ã¯ãããŸããïŒã æ¬è³ªçã«ããããã®ããŒã±ãã£ã³ã°ããŒãžã®ã»ãšãã©ã¯ããªãéçã§ãããæ¯æ¥ãŸãã¯æ¯é±äœæããã ãã§ååã§ãïŒãã¹ãŠã®ãªã¯ãšã¹ãã§ã¬ã³ããªã³ã°ããå¿ èŠããããŸãïŒã
ç§ã®è³ªå/èã:(å°æ¥çã«ïŒ getStaticPaths
ãã«ãŒããã©ã¡ãŒã¿ã§ã¯ãªããã®ã«åºã¥ããŠããŒãžãçæããæ¹æ³ã¯ãããŸããããªã¯ãšã¹ãã¬ãã«ã§ããããåãæ¿ããããã«äœ¿çšã§ããŸãïŒãµãŒããŒã¬ã¹ãªã©ïŒé¢æ°ã¯ã locale
åºã¥ããŠéçãªãã«ãæžã¿ã®çµæãè¿ããŸãïŒ
å
·äœçã«ã¯ã https://mysite.com/my-product
ãšhttps://mysite.co.uk/my-product
ã2ã€ã®ç°ãªãéçããŒãžãæäŸããããšãæå³ããŸããã次ã®ã¢ããªã50åçæãããããªã¯ãšã¹ãããšã«CMSãããããããããå¿
èŠã¯ãããŸããð
äºåã«æè¬ããããªãã®èããèãããšã«ç±å¿ã§ããç¹ã«ããã解決/åé¿ã§ããå°æ¥ã®ããã®ãã®ã§ããå Žåâ€ïž
SEOã®ãã©ãã£ãã¯ã®å€ãã©ã³ãã£ã³ã°ããŒãžãšãµãŒããŒã®è² è·ã軜æžããããã«SSGã䜿çšããããããã€ãã¬ãŒã·ã§ã³åŸãã¯ã©ã€ã¢ã³ãåŽã§ãã®ããŒãžã«ã«ãŒãã£ã³ã°ããããã«çŸåšã®ããŒã¿ã䜿çšããããšãããŠãŒã¹ã±ãŒã¹ãèããŠããŸãã ããã¯å¯èœã§ããããïŒ
ãããã£ãŠãåºæ¬çã«ãã®ããŒãžãžã®ã¯ã©ã€ã¢ã³ãåŽã«ãŒãã£ã³ã°ã§ã¯ãåäœã¯getInitialProps
ããã«ãªããŸãïŒããŒãžã衚瀺ãããåã«çŸåšã®ããŒã¿ããã§ãããããŸãïŒã ãŸãããã®ããŒãžãžã®ãµãŒããŒåŽã«ãŒãã£ã³ã°ã§ã¯ãéçhtmlãæäŸããŠãã€ãã¬ã€ãããïŒãªãã·ã§ã³ã§ïŒããã€ãã®APIå¿çããã§ããããŠãããŒãžäžã®ããŒã¿ãæŽæ°ããå¿
èŠããããŸãã
unstable_getStaticProps
ãè©ŠããŠã¿ããšããã楜ãã競åãçºçããŸããã getStaticProps
APIã«ãŒãã䜿çšããã®ã¯å°é£ã§ãã
ã³ãŒãã®ã»ãã³ãã£ã¯ã¹ã«ã¯æ³šæãæããªãã§ãã ãããããŒã¿ãã§ãããããŒã ãã«æ³šæããŠãã ããã
// pages/api/healthcheck.ts
import { NextApiResponse, NextApiRequest } from 'next';
export type ApiHealthCheckResponse = {
message: 'ok';
};
const healthCheckHandler = (
req: NextApiRequest,
res: NextApiResponse<ApiHealthCheckResponse | ''>,
) => {
if (req.method === 'GET') {
return res.status(200).json({ message: 'ok' });
}
return res.status(405).send('');
};
export default healthCheckHandler;
// pages/index.js
// ...
export async function unstable_getStaticProps() {
return {
props: {
healthcheck: (await fetch('localhost:3000/api/healthcheck').json())
},
};
}
ãµãŒããŒãå®è¡ãããŠããªããããããŒãžãã«ãã¯ãã«ãæã«ã¯ã©ãã·ã¥ããŸãã getStaticProps
ã¯ããŸãåçãªãã®ãšäžç·ã«äœ¿çšãã¹ãã§ã¯ãªãããããããæå¹ãªãŠãŒã¹ã±ãŒã¹ã§ãããã©ããã¯ããããŸããããå
±æããã®ã¯èå³æ·±ããšããžã±ãŒã¹ã ãšæããŸããïŒååŸãæ
åœããRouteAPIãšã³ããã€ã³ããå®å
šã«æ³åã§ããŸãïŒå¥ã®APIããã®ããŒã¿ãåãã©ãŒãããããŸãã
@martpieãã®ã³ã¡ã³ãããã§ãã¯ããããšããhttps ïŒ
Next.js 9.3ã§ã¯ã次äžä»£ã®éçãµã€ãçæïŒSSGïŒãµããŒããå®å®çãšããŠãªãªãŒã¹ãããŸããã
ãã®ãªãªãŒã¹ã«ã¯ãããã¬ãã¥ãŒã¢ãŒããã®ãµããŒãããŸãã¯éçã«äºåã¬ã³ããªã³ã°ãããããŒãžããã€ãã¹ããŠãèš±å¯ããããŠãŒã¶ãŒã«å¯ŸããŠãªã³ããã³ãã§ããŒãžãã¬ã³ããªã³ã°ããæ©èœãå«ãŸ
ããªãã¯ç§ãã¡ã®ããã°æçš¿ã§ããã«ã€ããŠãã£ãšèªãããšãã§ãããã¥ã¡ã³ãã«ã¢ã¯ã»ã¹ããŠãã ããã
Next.js GitHubã³ãã¥ããã£ã«è³ªåãæçš¿ããŠãã ããïŒ
ããã¯ãšãŠãã¯ãŒã«ã§ãïŒ é 匵ã£ãŠãããŠããããšãïŒ
ãã®æ°æ©èœã¯çŸåšãsagaãšreduxã§ã¯æ©èœããªãããã§ã
æãåèã«ãªãã³ã¡ã³ã
Next.js 9.3ã§ã¯ã次äžä»£ã®éçãµã€ãçæïŒSSGïŒãµããŒããå®å®çãšããŠãªãªãŒã¹ãããŸããã
ãã®ãªãªãŒã¹ã«ã¯ãããã¬ãã¥ãŒã¢ãŒããã®ãµããŒãããŸãã¯éçã«äºåã¬ã³ããªã³ã°ãããããŒãžããã€ãã¹ããŠãèš±å¯ããããŠãŒã¶ãŒã«å¯ŸããŠãªã³ããã³ãã§ããŒãžãã¬ã³ããªã³ã°ããæ©èœãå«ãŸ
ããªãã¯ç§ãã¡ã®ããã°æçš¿ã§ããã«ã€ããŠãã£ãšèªãããšãã§ãããã¥ã¡ã³ãã«ã¢ã¯ã»ã¹ããŠãã ããã