From 68eacafa67202511cc5ca5a91f3a6b923a7855cf Mon Sep 17 00:00:00 2001 From: Shaswat Saxena Date: Sun, 15 Mar 2020 13:07:38 +0530 Subject: [PATCH 1/2] Update with-typescript example to SSG --- examples/with-typescript/pages/users/[id].tsx | 50 +++++++++++++------ .../with-typescript/pages/users/index.tsx | 18 +++---- 2 files changed, 44 insertions(+), 24 deletions(-) diff --git a/examples/with-typescript/pages/users/[id].tsx b/examples/with-typescript/pages/users/[id].tsx index aa092621c30c809..919b98851d46946 100644 --- a/examples/with-typescript/pages/users/[id].tsx +++ b/examples/with-typescript/pages/users/[id].tsx @@ -1,5 +1,5 @@ import * as React from 'react' -import { NextPageContext } from 'next' +import { GetStaticProps, GetStaticPaths } from 'next' import { User } from '../../interfaces' import Layout from '../../components/Layout' @@ -11,19 +11,7 @@ type Props = { errors?: string } -class InitialPropsDetail extends React.Component { - static getInitialProps = async ({ query }: NextPageContext) => { - try { - const { id } = query - const item = await sampleFetchWrapper( - `http://localhost:3000/api/users/${Array.isArray(id) ? id[0] : id}` - ) - return { item } - } catch (err) { - return { errors: err.message } - } - } - +class StaticPropsDetail extends React.Component { render() { const { item, errors } = this.props @@ -49,4 +37,36 @@ class InitialPropsDetail extends React.Component { } } -export default InitialPropsDetail +export const getStaticPaths: GetStaticPaths = async () => { + const users: User[] = await sampleFetchWrapper( + 'http://localhost:3000/api/users' + ) + + // Get the paths we want to pre-render based on users + const paths = users.map(user => ({ + params: { id: user.id.toString() }, + })) + + // We'll pre-render only these paths at build time. + // { fallback: false } means other routes should 404. + return { paths, fallback: false } +} + +// This function gets called at build time on server-side. +// It won't be called on client-side, so you can even do +// direct database queries. See the "Technical details" section. +export const getStaticProps: GetStaticProps = async ({ params }) => { + try { + const id = params?.id + const item = await sampleFetchWrapper( + `http://localhost:3000/api/users/${Array.isArray(id) ? id[0] : id}` + ) + // By returning { props: item }, the StaticPropsDetail component + // will receive `item` as a prop at build time + return { props: { item } } + } catch (err) { + return { props: { errors: err.message } } + } +} + +export default StaticPropsDetail diff --git a/examples/with-typescript/pages/users/index.tsx b/examples/with-typescript/pages/users/index.tsx index 67638d050798822..a7095cedf7082ce 100644 --- a/examples/with-typescript/pages/users/index.tsx +++ b/examples/with-typescript/pages/users/index.tsx @@ -1,4 +1,4 @@ -import { NextPage } from 'next' +import { NextPage, GetStaticProps } from 'next' import Link from 'next/link' import Layout from '../../components/Layout' @@ -8,16 +8,15 @@ import { sampleFetchWrapper } from '../../utils/sample-api' type Props = { items: User[] - pathname: string } -const WithInitialProps: NextPage = ({ items, pathname }) => ( +const WithStaticProps: NextPage = ({ items }) => (

Users List

- Example fetching data from inside getInitialProps(). + Example fetching data from inside getStaticProps().

-

You are currently on: {pathname}

+

You are currently on: /users

@@ -27,15 +26,16 @@ const WithInitialProps: NextPage = ({ items, pathname }) => ( ) -WithInitialProps.getInitialProps = async ({ pathname }) => { - // Example for including initial props in a Next.js function component page. +export const getStaticProps: GetStaticProps = async () => { + // Example for including static props in a Next.js function component page. // Don't forget to include the respective types for any props passed into // the component. + const items: User[] = await sampleFetchWrapper( 'http://localhost:3000/api/users' ) - return { items, pathname } + return { props: { items } } } -export default WithInitialProps +export default WithStaticProps From 8a8f2cf1dc043c8f60c5c18dd568d5147565afe9 Mon Sep 17 00:00:00 2001 From: Luis Alvarez Date: Wed, 18 Mar 2020 15:06:53 -0500 Subject: [PATCH 2/2] Fixed usage of localhost inside SSG methods --- .../with-typescript/components/Layout.tsx | 3 ++- examples/with-typescript/pages/about.tsx | 2 +- .../with-typescript/pages/api/users/[id].ts | 17 ------------- examples/with-typescript/pages/index.tsx | 24 ++++++++----------- examples/with-typescript/pages/users/[id].tsx | 20 +++++----------- .../with-typescript/pages/users/index.tsx | 14 ++++------- examples/with-typescript/utils/sample-api.ts | 13 ---------- 7 files changed, 24 insertions(+), 69 deletions(-) delete mode 100644 examples/with-typescript/pages/api/users/[id].ts delete mode 100644 examples/with-typescript/utils/sample-api.ts diff --git a/examples/with-typescript/components/Layout.tsx b/examples/with-typescript/components/Layout.tsx index 12c97489b86ca96..8370123bbe19d70 100644 --- a/examples/with-typescript/components/Layout.tsx +++ b/examples/with-typescript/components/Layout.tsx @@ -28,7 +28,8 @@ const Layout: React.FunctionComponent = ({ |{' '} Users List - + {' '} + | Users API {children} diff --git a/examples/with-typescript/pages/about.tsx b/examples/with-typescript/pages/about.tsx index d3630721ebd9685..d8fa81877df63b2 100644 --- a/examples/with-typescript/pages/about.tsx +++ b/examples/with-typescript/pages/about.tsx @@ -1,4 +1,4 @@ -import * as React from 'react' +import React from 'react' import Link from 'next/link' import Layout from '../components/Layout' diff --git a/examples/with-typescript/pages/api/users/[id].ts b/examples/with-typescript/pages/api/users/[id].ts deleted file mode 100644 index 9018b5544960d7f..000000000000000 --- a/examples/with-typescript/pages/api/users/[id].ts +++ /dev/null @@ -1,17 +0,0 @@ -import { NextApiRequest, NextApiResponse } from 'next' -import { sampleUserData } from '../../../utils/sample-data' - -export default (req: NextApiRequest, res: NextApiResponse) => { - try { - const { id } = req.query - const selected = sampleUserData.find(data => data.id === Number(id)) - - if (!selected) { - throw new Error('Cannot find user') - } - - res.status(200).json(selected) - } catch (err) { - res.status(404).json({ statusCode: 404, message: err.message }) - } -} diff --git a/examples/with-typescript/pages/index.tsx b/examples/with-typescript/pages/index.tsx index 81347c6b63381f3..57f913a9b58818b 100644 --- a/examples/with-typescript/pages/index.tsx +++ b/examples/with-typescript/pages/index.tsx @@ -1,19 +1,15 @@ -import * as React from 'react' import Link from 'next/link' import Layout from '../components/Layout' -import { NextPage } from 'next' -const IndexPage: NextPage = () => { - return ( - -

Hello Next.js 👋

-

- - About - -

-
- ) -} +const IndexPage = () => ( + +

Hello Next.js 👋

+

+ + About + +

+
+) export default IndexPage diff --git a/examples/with-typescript/pages/users/[id].tsx b/examples/with-typescript/pages/users/[id].tsx index 919b98851d46946..81f15f721458951 100644 --- a/examples/with-typescript/pages/users/[id].tsx +++ b/examples/with-typescript/pages/users/[id].tsx @@ -1,17 +1,17 @@ -import * as React from 'react' +import React from 'react' import { GetStaticProps, GetStaticPaths } from 'next' import { User } from '../../interfaces' +import { sampleUserData } from '../../utils/sample-data' import Layout from '../../components/Layout' import ListDetail from '../../components/ListDetail' -import { sampleFetchWrapper } from '../../utils/sample-api' type Props = { item?: User errors?: string } -class StaticPropsDetail extends React.Component { +export default class StaticPropsDetail extends React.Component { render() { const { item, errors } = this.props @@ -38,12 +38,8 @@ class StaticPropsDetail extends React.Component { } export const getStaticPaths: GetStaticPaths = async () => { - const users: User[] = await sampleFetchWrapper( - 'http://localhost:3000/api/users' - ) - // Get the paths we want to pre-render based on users - const paths = users.map(user => ({ + const paths = sampleUserData.map(user => ({ params: { id: user.id.toString() }, })) @@ -54,13 +50,11 @@ export const getStaticPaths: GetStaticPaths = async () => { // This function gets called at build time on server-side. // It won't be called on client-side, so you can even do -// direct database queries. See the "Technical details" section. +// direct database queries. export const getStaticProps: GetStaticProps = async ({ params }) => { try { const id = params?.id - const item = await sampleFetchWrapper( - `http://localhost:3000/api/users/${Array.isArray(id) ? id[0] : id}` - ) + const item = sampleUserData.find(data => data.id === Number(id)) // By returning { props: item }, the StaticPropsDetail component // will receive `item` as a prop at build time return { props: { item } } @@ -68,5 +62,3 @@ export const getStaticProps: GetStaticProps = async ({ params }) => { return { props: { errors: err.message } } } } - -export default StaticPropsDetail diff --git a/examples/with-typescript/pages/users/index.tsx b/examples/with-typescript/pages/users/index.tsx index a7095cedf7082ce..7b3ee883b3a6754 100644 --- a/examples/with-typescript/pages/users/index.tsx +++ b/examples/with-typescript/pages/users/index.tsx @@ -1,16 +1,16 @@ -import { NextPage, GetStaticProps } from 'next' +import { GetStaticProps } from 'next' import Link from 'next/link' +import { User } from '../../interfaces' +import { sampleUserData } from '../../utils/sample-data' import Layout from '../../components/Layout' import List from '../../components/List' -import { User } from '../../interfaces' -import { sampleFetchWrapper } from '../../utils/sample-api' type Props = { items: User[] } -const WithStaticProps: NextPage = ({ items }) => ( +const WithStaticProps = ({ items }: Props) => (

Users List

@@ -30,11 +30,7 @@ export const getStaticProps: GetStaticProps = async () => { // Example for including static props in a Next.js function component page. // Don't forget to include the respective types for any props passed into // the component. - - const items: User[] = await sampleFetchWrapper( - 'http://localhost:3000/api/users' - ) - + const items: User[] = sampleUserData return { props: { items } } } diff --git a/examples/with-typescript/utils/sample-api.ts b/examples/with-typescript/utils/sample-api.ts deleted file mode 100644 index 3f193c204668767..000000000000000 --- a/examples/with-typescript/utils/sample-api.ts +++ /dev/null @@ -1,13 +0,0 @@ -import fetch from 'isomorphic-unfetch' - -export async function sampleFetchWrapper( - input: RequestInfo, - init?: RequestInit -) { - try { - const data = await fetch(input, init).then(res => res.json()) - return data - } catch (err) { - throw new Error(err.message) - } -}