Skip to content
This repository has been archived by the owner on May 6, 2022. It is now read-only.

added _app.js and _document.js and set up getInitialProps #106

Closed
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
47 changes: 24 additions & 23 deletions .eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,26 +1,27 @@
{
"env": {
"browser": true,
"es6": true,
"jest": true
"env": {
"browser": true,
"es6": true,
"jest": true
},
"extends": ["airbnb", "prettier"],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"extends": ["airbnb", "prettier"],
"globals": {
"Atomics": "readonly",
"SharedArrayBuffer": "readonly"
},
"parser": "babel-eslint",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": [
"react"
],
"rules": {
"react/prop-types": ["error"]
}
"ecmaVersion": 2018,
"sourceType": "module"
},
"plugins": ["react"],
"rules": {
"react/prop-types": ["error"],
"react/jsx-props-no-spreading": ["warn"],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you revert these rule changes and use comments to exclude single lines please?

"react/forbid-prop-types": ["warn"],
"no-unused-vars": ["warn"]
}
}
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
],
"coveragePathIgnorePatterns": [
"<rootDir>/build/",
"<rootDir>/default/src/pages/_document.jsx",
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed since it is basic default code with only changes to head, but items in the head are tested in separate component tests.

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It shouldn't be ignored from code coverage

"<rootDir>/out/",
"<rootDir>/.next/",
"<rootDir>/node_modules/",
Expand Down
1 change: 1 addition & 0 deletions templates/default.json
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
"collectCoverageFrom": ["**/*.{js,jsx,ts,tsx}"],
"coveragePathIgnorePatterns": [
"<rootDir>/build/",
"<rootDir>/src/pages/_document.jsx",
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Shouldn't be ignored - not a good example to set. If you look at the client-internal repo forked from this, I believe I have an example of testing the _app.jsx or _document.jsx

"<rootDir>/out/",
"<rootDir>/.next/",
"<rootDir>/node_modules/",
Expand Down
9 changes: 8 additions & 1 deletion templates/default/babelrc
Original file line number Diff line number Diff line change
@@ -1,3 +1,10 @@
{
"presets": ["@babel/preset-env","next/babel"]
"presets": [
[
"next/babel",
{
"preset-env": { "targets": { "node": "current" } }
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this was required to be able to extend a class in document.js

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixes #127?

}
]
]
}
5 changes: 4 additions & 1 deletion templates/default/eslintrc.json
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
},
"plugins": ["react"],
"rules": {
"react/prop-types": ["error"]
"react/prop-types": ["error"],
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please revert these and use comments for single-line excludes

"react/jsx-props-no-spreading": ["warn"],
"react/forbid-prop-types": ["warn"],
"no-unused-vars": ["warn"]
}
}

This file was deleted.

This file was deleted.

This file was deleted.

17 changes: 17 additions & 0 deletions templates/default/src/components/organisms/PageTitle/PageTitle.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import React from 'react'
import PropTypes from 'prop-types'
import Head from 'next/head'

const PageTitle = ({ title }) => {
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

change to title since that is the one thing that we may want to change from components outside document.js

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is the key really necessary? I don't think eslint-react nor react is going to issue a warning here since it's wrapped in the element

return (
<Head>
<title key="title">{title}</title>
</Head>
)
}

PageTitle.propTypes = {
title: PropTypes.string.isRequired
}

export default PageTitle
Original file line number Diff line number Diff line change
@@ -1,36 +1,30 @@
import React from 'react'
import ShallowRenderer from 'react-test-renderer/shallow'
import GlobalHead from '.'
import PageTitle from '.'

describe('GlobalHead', () => {
describe('PageTitle', () => {
// Test uses ShallowRenderer.render() instead of TestRenderer.create()
// because <GlobalHead> encapsulates NextJS <Head> which in turn uses
// because <PageTitle> encapsulates NextJS <Head> which in turn uses
// React <Helmet> and Helmet doesn't show up in a normal component render.
it('creates a <head> element suitable for global usage across all pages', () => {
const renderer = new ShallowRenderer();
renderer.render(
<GlobalHead title="mock title for test" />
)
const renderer = new ShallowRenderer()
renderer.render(<PageTitle title="mock title for test" />)
const result = renderer.getRenderOutput()
expect(result).toMatchSnapshot()
})
it('populates the specified page title', () => {
const title = "mockTitle"
const renderer = new ShallowRenderer();
renderer.render(
<GlobalHead title={title} />
)
const title = 'mockTitle'
const renderer = new ShallowRenderer()
renderer.render(<PageTitle title={title} />)
const result = renderer.getRenderOutput()
// Expect a React module with a populated <title>
expect(result.props.children).toEqual(
expect.arrayContaining([
expect.objectContaining({
type: 'title',
props: {
children: title
}
})
])
expect.objectContaining({
type: 'title',
props: {
children: title
}
})
)
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
// Jest Snapshot v1, https://goo.gl/fbAQLP

exports[`PageTitle creates a <head> element suitable for global usage across all pages 1`] = `
<Head>
<title>
mock title for test
</title>
</Head>
`;
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './PageTitle'
37 changes: 37 additions & 0 deletions templates/default/src/pages/_document.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/* _document is only rendered on the server side and not on the client side
* Event handlers like onClick can't be added to this file
*/
import React from 'react'
import Document, { Html, Head, Main, NextScript } from 'next/document'
import Flavicon from '../components/molecules/Favicon'
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Flavicon? Is that a typo?

import Manifest from '../components/molecules/Manifest'

class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx)
return { ...initialProps }
}

render() {
return (
<Html lang="en">
<Head>
{/* HEADER ELEMENTS THAT GO HERE:
* meta tags, global scripts, global stylesheets, rel links, etc.
* Tracking scripts like Google Analytics (try https://github.com/react-ga/react-ga)
*/}
<Flavicon />
<Manifest />
</Head>
<body>
{/* NOSCRIPT: place them inside a new <noscript> tag here */}
<Main />
<NextScript />
{/* FOOTER: If your footer will not change based on api calls, place here, otherwise place in _app.js */}
</body>
</Html>
)
}
}

export default MyDocument
9 changes: 3 additions & 6 deletions templates/default/src/pages/example/second-page/index.jsx
Original file line number Diff line number Diff line change
@@ -1,18 +1,15 @@
import React from 'react'
import Link from 'next/link'
import GlobalHead from '../../../components/organisms/GlobalHead'
import PageTitle from '../../../components/organisms/PageTitle'

const SecondPage = () => {
return (
<>
<GlobalHead title="Second Page - %%APPNAME%%" />
<PageTitle title="Second Page - %%APPNAME%%" />
<main>
<p>
This is another page at a different URL.
</p>
<p>This is another page at a different URL.</p>
<p>
Return to the

<Link href="/">homepage</Link>
</p>
</main>
Expand Down
16 changes: 12 additions & 4 deletions templates/default/src/pages/index/index.jsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,29 @@
import React from 'react'
import Link from 'next/link'
import GlobalHead from '../../components/organisms/GlobalHead'
import PageTitle from '../../components/organisms/PageTitle'

const Home = () => {
return (
<>
<GlobalHead title="%%APPNAME%%" />
<PageTitle title="%%APPNAME%%" />
<p>Welcome to the boilerplate React app using NextJS!</p>
<p>
Try navigating to

<Link href="/example/second-page">another page</Link>

and observe the URL changing
</p>
</>
)
}

// estlin-disable-next-line
Home.getInitialProps = async context => {
/* Here you can make your pre-fetch for this page, it's a pre-rendering step
* only available for pages.
* Useful parameters in context object: req, res, query (passed from 4th render argument)
* It expects an object with props to be returned
*/
return {}
}

export default Home