Slide 1

Slide 1 text

Radoslav Stankov 25/02/2020

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

No content

Slide 4

Slide 4 text

https://speakerdeck.com/rstankov

Slide 5

Slide 5 text

No content

Slide 6

Slide 6 text

What is NEXT.js?

Slide 7

Slide 7 text

https://nextjs.org

Slide 8

Slide 8 text

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

Slide 9

Slide 9 text

No content

Slide 10

Slide 10 text

No content

Slide 11

Slide 11 text

components/ graphql/ hooks/ layouts/ pages/ routes/ server/ static/ styles/ types/ utils/ config.ts paths.ts

Slide 12

Slide 12 text

export default { root: () => '/', static: { about() => '/about', // ... } profiles: { people: () => '/people', show: ({ slug }: { slug: string }) => `/@${slug}`, // ... }, // ... }; path.ts

Slide 13

Slide 13 text

import paths from 'ph/paths'; 
 paths.root(); // => / paths.static.about(); // => /about/ paths.profiles.people(); // => /people paths.profiles.show(profile); // => /@rstankov

Slide 14

Slide 14 text

Handling links

Slide 15

Slide 15 text

Slide 16

Slide 16 text

Slide 17

Slide 17 text

import * as React from 'react'; import Link from 'next/link'; interface IProps extends React.AnchorHTMLAttributes { to: string; // we can add more properties we need from next/link in the future } interface IProps extends React.AnchorHTMLAttributes { to: string; prefetch?: boolean; } export default React.forwardRef(({ to, prefetch, ...props }: IProps, ref: any) => { return ( ); });

Slide 18

Slide 18 text

Slide 19

Slide 19 text

Slide 20

Slide 20 text

Product 1;

Slide 21

Slide 21 text

Product 1;

Slide 22

Slide 22 text

export default { about: '/about', contact: '/contact', product(product: { id: string }) { return { href: '/products/[id]', as: `/products/${id}`, }; }, };

Slide 23

Slide 23 text

interface IProps extends React.AnchorHTMLAttributes { to: string | { href: string, as: string }; prefetch?: boolean; } export default React.forwardRef( ({ to, prefetch, ...props }: IProps, ref: any) => { if (typeof to === 'string') { return ( ); } return ( ); }, );

Slide 24

Slide 24 text

https://blog.logrocket.com/dealing-with-links-in-next-js/

Slide 25

Slide 25 text

components/ graphql/ hooks/ layouts/ pages/ routes/ server/ static/ styles/ types/ utils/ config.ts paths.ts

Slide 26

Slide 26 text

pages/profiles/[slug]/index.ts

Slide 27

Slide 27 text

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

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

components/ graphql/ hooks/ layouts/ pages/ routes/ server/ static/ styles/ types/ utils/ config.ts paths.ts

Slide 30

Slide 30 text

Component as directory routing/ profiles/ show/ SubComponent1/ SubComponent2/ Query.graphql index.js styles.css utils.js

Slide 31

Slide 31 text

Loading State Page Life Cycle

Slide 32

Slide 32 text

Loading State Page Life Cycle

Slide 33

Slide 33 text

Loading State Error State Page Life Cycle

Slide 34

Slide 34 text

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

Slide 35

Slide 35 text

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

Slide 36

Slide 36 text

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

Slide 37

Slide 37 text

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

Slide 38

Slide 38 text

wraps Apollo query handles page states handles errors handles authentication handles authorization handles SEO tags handles feature flags type safe createPage createPage({ component: query: queryVariables: requireLogin: requirePermissions: requireFeature: tags: title: titleNoPrefix: );

Slide 39

Slide 39 text

import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import { ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage({ 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 */ ), });

Slide 40

Slide 40 text

import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import { ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage({ 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 */ ), });

Slide 41

Slide 41 text

import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import { ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage({ 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 */ ), });

Slide 42

Slide 42 text

import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import { ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage({ 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 */ ), });

Slide 43

Slide 43 text

import createPage from '~/utils/createPage'; import ProfileLayout from '~/layouts/Profile'; import { ProfileShowPage } from '~/graphql/types'; import QUERY from './Query'; export default createPage({ 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 */ ), });

Slide 44

Slide 44 text

No content

Slide 45

Slide 45 text

https://github.com/zeit/next.js/tree/canary/examples Examples

Slide 46

Slide 46 text

Recap

Slide 47

Slide 47 text

Next.js is awesome

Slide 48

Slide 48 text

Rado approves

Slide 49

Slide 49 text

No content

Slide 50

Slide 50 text

No content

Slide 51

Slide 51 text

https://speakerdeck.com/rstankov Thanks

Slide 52

Slide 52 text

No content