Intro to Next.js

Intro to Next.js

7a0e72a6f55811246bb5d9a946fd2e49?s=128

Radoslav Stankov

February 24, 2020
Tweet

Transcript

  1. Radoslav Stankov 25/02/2020

  2. Radoslav Stankov @rstankov blog.rstankov.com
 twitter.com/rstankov
 github.com/rstankov
 speakerdeck.com/rstankov

  3. None
  4. https://speakerdeck.com/rstankov

  5. None
  6. What is NEXT.js?

  7. https://nextjs.org

  8. no need to manage your Babel/Webpack
 server side rendering code

    splitting by default decent routing system (optional) API support dynamic loading support build in support for TypeScript CSS modules
  9. None
  10. None
  11. components/ graphql/ hooks/ layouts/ pages/ routes/ server/ static/ styles/ types/

    utils/ config.ts paths.ts
  12. export default { root: () => '/', static: { about()

    => '/about', // ... } profiles: { people: () => '/people', show: ({ slug }: { slug: string }) => `/@${slug}`, // ... }, // ... }; path.ts
  13. import paths from 'ph/paths'; 
 paths.root(); // => / paths.static.about();

    // => /about/ paths.profiles.people(); // => /people paths.profiles.show(profile); // => /@rstankov
  14. Handling links

  15. <Link href="/about"> <a>About</a> </Link>

  16. <Link href="/about"> <a>About</a> </Link>

  17. import * as React from 'react'; import Link from 'next/link';

    interface IProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> { to: string; // we can add more properties we need from next/link in the future } interface IProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> { to: string; prefetch?: boolean; } export default React.forwardRef(({ to, prefetch, ...props }: IProps, ref: any) => { return ( <Link href={to} prefetch={prefetch || false}> <a {...props} ref={ref} /> </Link> ); });
  18. <Link href="/products/[id]" as="/product/1"> <a>Product 1</a> </Link>

  19. <Link href="/products/[id]" as="/product/1"> <a>Product 1</a> </Link>

  20. <Link to={paths.product(product)}>Product 1</Link>;

  21. <Link to={paths.product(product)}>Product 1</Link>;

  22. export default { about: '/about', contact: '/contact', product(product: { id:

    string }) { return { href: '/products/[id]', as: `/products/${id}`, }; }, };
  23. interface IProps extends React.AnchorHTMLAttributes<HTMLAnchorElement> { to: string | { href:

    string, as: string }; prefetch?: boolean; } export default React.forwardRef( ({ to, prefetch, ...props }: IProps, ref: any) => { if (typeof to === 'string') { return ( <Link href={to} prefetch={prefetch || false}> <a {...props} ref={ref} /> </Link> ); } return ( <Link href={to.href} as={to.as} prefetch={prefetch || false}> <a {...props} ref={ref} /> </Link> ); }, );
  24. https://blog.logrocket.com/dealing-with-links-in-next-js/

  25. components/ graphql/ hooks/ layouts/ pages/ routes/ server/ static/ styles/ types/

    utils/ config.ts paths.ts
  26. pages/profiles/[slug]/index.ts

  27. import page from '~/routes/profiles/show'; export default page; pages/profiles/[slug]/index.ts

  28. import page from '~/routes/profiles/show'; export default page; pages/profiles/[slug]/index.ts

  29. components/ graphql/ hooks/ layouts/ pages/ routes/ server/ static/ styles/ types/

    utils/ config.ts paths.ts
  30. Component as directory routing/ profiles/ show/ SubComponent1/ SubComponent2/ Query.graphql index.js

    styles.css utils.js
  31. Loading State Page Life Cycle

  32. Loading State Page Life Cycle

  33. Loading State Error State Page Life Cycle

  34. Loading State Not Found Error Server Error Authorization Error Authentication

    Error Error State Page Life Cycle
  35. Loading State Not Found Error Server Error Authorization Error Authentication

    Error Error State Loaded State Page Life Cycle
  36. Loading State Not Found Error Server Error Authorization Error Authentication

    Error SEO Error State Analytics Loaded State Page Life Cycle ???
  37. Loading State Not Found Error Server Error Authorization Error Authentication

    Error SEO Error State Analytics Loaded State render Page Life Cycle ???
  38. wraps Apollo query handles page states handles errors handles authentication

    handles authorization handles SEO tags handles feature flags type safe createPage createPage<QueryData>({ component: query: queryVariables: requireLogin: requirePermissions: requireFeature: tags: title: titleNoPrefix: );
  39. import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import {

    ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage<ProfileShowPage>({ query: QUERY, queryVariables: ({ slug }) => ({ slug }), requireLogin: true, requirePermissions: ({ profile }) => profile.canManage, requireFeature: 'feature_flag', tags: ({ profile }) => profile.seoTags, title: ({ profile }) => profile.name, component: ({ data: { profile } }) => ( /* code */ ), });
  40. import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import {

    ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage<ProfileShowPage>({ query: QUERY, queryVariables: ({ slug }) => ({ slug }), requireLogin: true, requirePermissions: ({ profile }) => profile.canManage, requireFeature: 'feature_flag', tags: ({ profile }) => profile.seoTags, title: ({ profile }) => profile.name, component: ({ data: { profile } }) => ( /* code */ ), });
  41. import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import {

    ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage<ProfileShowPage>({ query: QUERY, queryVariables: ({ slug }) => ({ slug }), requireLogin: true, requirePermissions: ({ profile }) => profile.canManage, requireFeature: 'feature_flag', tags: ({ profile }) => profile.seoTags, title: ({ profile }) => profile.name, component: ({ data: { profile } }) => ( /* code */ ), });
  42. import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import {

    ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage<ProfileShowPage>({ query: QUERY, queryVariables: ({ slug }) => ({ slug }), requireLogin: true, requirePermissions: ({ profile }) => profile.canManage, requireFeature: 'feature_flag', tags: ({ profile }) => profile.seoTags, title: ({ profile }) => profile.name, component: ({ data: { profile } }) => ( /* code */ ), });
  43. import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import {

    ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage<ProfileShowPage>({ query: QUERY, queryVariables: ({ slug }) => ({ slug }), requireLogin: true, requirePermissions: ({ profile }) => profile.canManage, requireFeature: 'feature_flag', tags: ({ profile }) => profile.seoTags, title: ({ profile }) => profile.name, component: ({ data: { profile } }) => ( /* code */ ), });
  44. None
  45. https://github.com/zeit/next.js/tree/canary/examples Examples

  46. Recap

  47. Next.js is awesome

  48. Rado approves

  49. None
  50. None
  51. https://speakerdeck.com/rstankov Thanks

  52. None