-
Notifications
You must be signed in to change notification settings - Fork 83
/
_app.js
110 lines (95 loc) · 3.38 KB
/
_app.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import App, { Container } from "next/app";
import Head from "next/head";
import { NextSeo } from "next-seo";
import Navigation from "../components/Navigation";
import { createSEOConfig } from "../utils/seo";
import getPostData from "../utils/get-post-data";
import BlogEngine from "../utils/blog-engine";
import { renderLayout } from "../utils/render-app-layout";
import Footer from "../components/Footer";
import { checkForSW } from "../utils/check-for-sw";
import { FaBars } from "react-icons/fa";
import { globalStyles } from "../styles";
export default class MyApp extends App {
constructor(props) {
super(props);
this.state = { navOpen: false, postData: props.postData };
}
static async getInitialProps({ Component, router, ctx }) {
let pageProps = {};
if (Component.getInitialProps) {
pageProps = await Component.getInitialProps(ctx);
}
const [allData, postData] = await Promise.all([
BlogEngine(),
getPostData(router)
]).catch(error =>
console.error("Error in _app.js getInitialProps()", error)
);
const propsObj = Object.assign(
{},
{ postData, allData, ...pageProps }
);
return { ...propsObj };
}
async componentDidMount() {
await checkForSW();
}
async componentDidUpdate(prevProps, prevState) {
const postData = await getPostData(this.props.router);
if (!prevState.postData || postData.name !== this.state.postData.name) {
this.setState({ postData });
}
}
handleToggleNavigation = () => {
this.setState({
navOpen: !this.state.navOpen
});
};
render() {
const { postData } = this.state;
const seoData = createSEOConfig(postData);
if (postData) {
const tagsString = postData.tags.join(", ");
return (
<React.Fragment>
{/* (1) SEO */}
<Head>
<meta name="keywords" content={tagsString} />
</Head>
<NextSeo config={seoData} />
{/* (2) navigation */}
<Navigation
open={this.state.navOpen}
toggleNavigation={this.handleToggleNavigation}
/>
<button
type="button"
role="button"
aria-label="open navigation"
className="icon-button hamburger"
onClick={this.handleToggleNavigation}>
<FaBars size={20} />
</button>
{/* (3) page body */}
<React.Fragment>
{renderLayout(this.props, this.state)}
</React.Fragment>
{/* (4) footer */}
<Footer />
{/* (5) global and local styles */}
<style global jsx>
{globalStyles}
</style>
<style jsx>{`
.icon-button {
margin: 15px;
}
`}</style>
</React.Fragment>
);
} else {
return null;
}
}
}