Skip to content

nejilabs/jackherrington-introtoreact-reactjsnextjsreduxzustandmobx-9-20210412-pokemonapp-nextjs-ssg-deploy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

9-20210412-pokemonapp-nextjs-ssg

Table of Contents


17 - 8:47 Introduction To React #17 | Static Site Generation (SSG)

Description: We statically generate the Pokemon detail page using NextJS' Static Site Generation (SSG) functionality.

17.1 Project Setup

just make a copy of the ssr version and rename it accordingly with -ssg. then edit accordingly such as package.json and README nyehehe

17.2 Moving pokemon.json from public/ to src/

this is because ssg happens at build time.

now we then change the route of pokemon.json to normal direct pathing not link.

Basic Features: Data Fetching | Next.js

as seen instead of just one function getServerSideProps() from ssr, we have two: getStaticPaths() and getStaticProps()

pages/pokemon/[id].js

import { useRouter } from "next/router";
import { observer } from "mobx-react";
import {
  CssBaseline,
  Table,
  TableBody,
  TableCell,
  TableHead,
  TableRow,
} from "@material-ui/core";
import styled from "@emotion/styled";

import store from "../../src/store";

const PageContainer = styled.div`
  margin: auto;
  width: 800px;
  padding-top: 1em;
`;
const TypeHeader = styled.span`
  font-weight: bold;
`;

export async function getStaticPaths() {
  const pokemons = require('../../src/pokemon.json')
  return {
    paths: pokemons.map((pokemon) => ({
      params: {
        id: pokemon.id.toString()
      }
    })),
    fallback: false
  };
}

export async function getStaticProps(context) {
  const pokemons = require('../../src/pokemon.json')
  const pokemon = pokemons.find((p) => p.id === parseInt(context.params.id));
  return {
    props: {
      pokemon
    },
  }
}

export default ({ pokemon }) => {
  const router = useRouter();

  return (
    <PageContainer>
      <CssBaseline />

      <div>
        {pokemon && (
          <>
            <h1>{pokemon.name.english}</h1>
            <p>
              <TypeHeader>Type:</TypeHeader> {" " + pokemon.type.join(", ")}
            </p>
            <Table>
              <TableHead>
                <TableRow>
                  <TableCell>Attribute</TableCell>
                  <TableCell>Value</TableCell>
                </TableRow>
              </TableHead>
              <TableBody>
                {Object.keys(pokemon.base).map((key) => (
                  <TableRow key={key}>
                    <TableCell>{key}</TableCell>
                    <TableCell>{pokemon.base[key]}</TableCell>
                  </TableRow>
                ))}
              </TableBody>
            </Table>
          </>
        )}
      </div>
    </PageContainer>
  );
};

then at pages/index.js

// START: IMPORTS
import styled from "@emotion/styled";
import { CssBaseline } from "@material-ui/core";

import { observer } from 'mobx-react'
import store from '../src/store'

import PokemonInfo from "../components/PokemonInfo";
import PokemonFilter from "../components/PokemonFilter";
import PokemonTable from "../components/PokemonTable";
// END: IMPORTS

// START: STYLED COMPONENTS
const Title = styled.h1`
  text-align: center;
`;
const PageContainer = styled.div`
  margin: auto;
  width: 800px;
  padding-top: 1em;
`;
const TwoColumnLayout = styled.div`
  display: grid;
  grid-template-columns: 80% 20%;
  grid-column-gap: 1rem;
`;
// END: STYLED COMPONENTS

// START: COMPONENT ---
const Home = () => {
  // Start: Templates
  if (!store.pokemons) {
    return <div>Loading data</div>;
  }
  return (
    <PageContainer>
      <CssBaseline />
      <Title>Pokemon Search</Title>
      <TwoColumnLayout>
        <div>
          <PokemonFilter />
          <PokemonTable />
        </div>
        <PokemonInfo />
      </TwoColumnLayout>
    </PageContainer>
  );
  // End: Templates
}
// END: COMPONENT ---

export default observer(Home);

and store.js @states

pokemons = require('./pokemon.json')

17.3 Build and Export

package.json @scripts

"export": "next export"

Terminal

yarn build
yarn export
cd out
PORT=3000 npx serve

then check http://localhost:3000

(dont forget to close first the dev server)

you can check at your browser dev tools at lighthouse for the performance

17.4 Putting this on Github

Example on Vercel next.js examples Github

vercel/next.js

17.4.1 Create a new github repo

17.4.2 Create next.config.js

const debug = process.env.NODE_ENV !== 'production'

module.exports = {
  basePath: !debug ? '/<name-of-the-app>' : '',
  assetPrefix: !debug ? '/<name-of-the-app>/' : '',
}

17.4.3 remove /out/ from gitignore

17.4.4 add deploy script to package.json

"deploy": "rm -rf node_modules/.cache && next build && next export && touch out/.nojekyll && git add out/ && git commit -m \"Deploy Next.js to gh-pages\" && git subtree push --prefix out origin gh-pages"

17.4.5 push changes to github

git add, git commit 
git remote
git push

17.4.6 Deploy to GH Pages

yarn deploy

then go to settings of github repo


This is a Next.js project bootstrapped with create-next-app.

Getting Started

First, run the development server:

npm run dev
# or
yarn dev

Open http://localhost:3000 with your browser to see the result.

You can start editing the page by modifying pages/index.js. The page auto-updates as you edit the file.

API routes can be accessed on http://localhost:3000/api/hello. This endpoint can be edited in pages/api/hello.js.

The pages/api directory is mapped to /api/*. Files in this directory are treated as API routes instead of React pages.

Learn More

To learn more about Next.js, take a look at the following resources:

You can check out the Next.js GitHub repository - your feedback and contributions are welcome!

Deploy on Vercel

The easiest way to deploy your Next.js app is to use the Vercel Platform from the creators of Next.js.

Check out our Next.js deployment documentation for more details.