Use built in gatsby head in favor of react-helmet
Luke Karrys committed
Oct 20, 2023 at 17:05 UTC
8c69a786853092db8f9be07622e5c08776444b67
10 files changed
+49
-92
content/index.mdx
+1
-1
@@ -1,5 +1,5 @@
1
---
2
-title: npm Documentation
2
+title: npm Docs
3
edit_on_github: false
4
---
5
gatsby-config.js
+1
-1
@@ -58,13 +58,13 @@ module.exports = {
58
description: 'Documentation for the npm registry, website, and command-line interface',
59
lang: 'en',
60
imageUrl: 'https://user-images.githubusercontent.com/29712634/81721690-e2fb5d80-9445-11ea-8602-4b2294c964f3.png',
61
+ repositoryUrl: 'https://github.com/npm/documentation',
62
},
63
flags: {
64
DEV_SSR: !!process.env.DEV_SSR,
65
},
66
plugins: [
67
'gatsby-plugin-styled-components',
67
- 'gatsby-plugin-react-helmet',
68
'gatsby-transformer-yaml',
69
{
70
resolve: 'gatsby-plugin-mdx',
gatsby-node.js
+5
-5
@@ -1,13 +1,14 @@
1
-const {resolve, join, relative} = require('path')
1
+const {join, relative} = require('path')
2
const {Octokit: CoreOctokit} = require('@octokit/rest')
3
const {throttling} = require('@octokit/plugin-throttling')
4
const {retry} = require('@octokit/plugin-retry')
5
6
const CI = !!process.env.CI
7
+const CWD = process.cwd()
8
+const SRC = join(CWD, 'src')
9
const REPO_URL = 'https://github.com/npm/documentation'
10
const NWO = new URL(REPO_URL).pathname.slice(1)
11
const REPO_BRANCH = 'main'
10
-const CWD = process.cwd()
12
const TEST_CONTRIBUTORS = [
13
{
14
author: {login: 'mona'},
@@ -66,7 +67,7 @@ exports.onCreateWebpackConfig = ({actions}) => {
67
actions.setWebpackConfig({
68
resolve: {
69
alias: {
69
- '~': resolve(__dirname, 'src/'),
70
+ '~': SRC,
71
},
72
extensions: ['.js'],
73
},
@@ -172,7 +173,6 @@ const createPage = async (
173
const context = {
174
mdxId: id,
175
tableOfContents: getTableOfConents(tableOfContents),
175
- repositoryUrl: REPO_URL,
176
}
177
// edit_on_github: false in frontmatter will not include editUrl and contributors
178
// on the page. this is used for policy pages as well as some index pages that don't
@@ -184,7 +184,7 @@ const createPage = async (
184
185
actions.createPage({
186
path: pageSlug,
187
- component: contentFilePath,
187
+ component: `${join(SRC, 'head.js')}?__contentFilePath=${contentFilePath}`,
188
context,
189
})
190
package-lock.json
-44
@@ -29,7 +29,6 @@
29
"gatsby-plugin-manifest": "^5.12.1",
30
"gatsby-plugin-mdx": "^5.12.1",
31
"gatsby-plugin-meta-redirect": "^1.1.1",
32
- "gatsby-plugin-react-helmet": "^6.12.0",
32
"gatsby-plugin-styled-components": "^6.12.0",
33
"gatsby-source-filesystem": "^5.12.0",
34
"gatsby-transformer-yaml": "^5.12.0",
@@ -41,7 +40,6 @@
40
"react-addons-text-content": "^0.0.4",
41
"react-dom": "^18.2.0",
42
"react-focus-on": "^3.9.1",
44
- "react-helmet": "^6.1.0",
43
"styled-components": "^5.3.11",
44
"styled-system": "^5.1.5"
45
},
@@ -17748,21 +17746,6 @@
17746
"gatsby": "^5.0.0-next"
17747
}
17748
},
17751
- "node_modules/gatsby-plugin-react-helmet": {
17752
- "version": "6.12.0",
17753
- "resolved": "https://registry.npmjs.org/gatsby-plugin-react-helmet/-/gatsby-plugin-react-helmet-6.12.0.tgz",
17754
- "integrity": "sha512-agcBCT9H8nlpkAU3D1fUeJbjh7IMPjGO/njoa7avIYLGsQ2nyGlHwcrEmS2zBHxYKaxPkztvr47OpCdnuEIvEw==",
17755
- "dependencies": {
17756
- "@babel/runtime": "^7.20.13"
17757
- },
17758
- "engines": {
17759
- "node": ">=18.0.0"
17760
- },
17761
- "peerDependencies": {
17762
- "gatsby": "^5.0.0-next",
17763
- "react-helmet": "^5.1.3 || ^6.0.0"
17764
- }
17765
- },
17749
"node_modules/gatsby-plugin-styled-components": {
17750
"version": "6.12.0",
17751
"resolved": "https://registry.npmjs.org/gatsby-plugin-styled-components/-/gatsby-plugin-styled-components-6.12.0.tgz",
@@ -28009,11 +27992,6 @@
27992
"resolved": "https://registry.npmjs.org/react-error-overlay/-/react-error-overlay-6.0.11.tgz",
27993
"integrity": "sha512-/6UZ2qgEyH2aqzYZgQPxEnz33NJ2gNsnHA2o5+o4wW9bLM/JYQitNP9xPhsXwC08hMMovfGe/8retsdDsczPRg=="
27994
},
28012
- "node_modules/react-fast-compare": {
28013
- "version": "3.2.2",
28014
- "resolved": "https://registry.npmjs.org/react-fast-compare/-/react-fast-compare-3.2.2.tgz",
28015
- "integrity": "sha512-nsO+KSNgo1SbJqJEYRE9ERzo7YtYbou/OqjSQKxV7jcKox7+usiUVZOAC+XnDOABXggQTno0Y1CpVnuWEc1boQ=="
28016
- },
27995
"node_modules/react-focus-lock": {
27996
"version": "2.9.6",
27997
"resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.6.tgz",
@@ -28062,20 +28040,6 @@
28040
}
28041
}
28042
},
28065
- "node_modules/react-helmet": {
28066
- "version": "6.1.0",
28067
- "resolved": "https://registry.npmjs.org/react-helmet/-/react-helmet-6.1.0.tgz",
28068
- "integrity": "sha512-4uMzEY9nlDlgxr61NL3XbKRy1hEkXmKNXhjbAIOVw5vcFrsdYbH2FEwcNyWvWinl103nXgzYNlns9ca+8kFiWw==",
28069
- "dependencies": {
28070
- "object-assign": "^4.1.1",
28071
- "prop-types": "^15.7.2",
28072
- "react-fast-compare": "^3.1.1",
28073
- "react-side-effect": "^2.1.0"
28074
- },
28075
- "peerDependencies": {
28076
- "react": ">=16.3.0"
28077
- }
28078
- },
28043
"node_modules/react-intersection-observer": {
28044
"version": "9.5.2",
28045
"resolved": "https://registry.npmjs.org/react-intersection-observer/-/react-intersection-observer-9.5.2.tgz",
@@ -28200,14 +28164,6 @@
28164
"node": ">=0.4.0"
28165
}
28166
},
28203
- "node_modules/react-side-effect": {
28204
- "version": "2.1.2",
28205
- "resolved": "https://registry.npmjs.org/react-side-effect/-/react-side-effect-2.1.2.tgz",
28206
- "integrity": "sha512-PVjOcvVOyIILrYoyGEpDN3vmYNLdy1CajSFNt4TDsVQC5KpTijDvWVoR+/7Rz2xT978D8/ZtFceXxzsPwZEDvw==",
28207
- "peerDependencies": {
28208
- "react": "^16.3.0 || ^17.0.0 || ^18.0.0"
28209
- }
28210
- },
28167
"node_modules/react-style-singleton": {
28168
"version": "2.2.1",
28169
"resolved": "https://registry.npmjs.org/react-style-singleton/-/react-style-singleton-2.2.1.tgz",
package.json
-2
@@ -44,7 +44,6 @@
44
"gatsby-plugin-manifest": "^5.12.1",
45
"gatsby-plugin-mdx": "^5.12.1",
46
"gatsby-plugin-meta-redirect": "^1.1.1",
47
- "gatsby-plugin-react-helmet": "^6.12.0",
47
"gatsby-plugin-styled-components": "^6.12.0",
48
"gatsby-source-filesystem": "^5.12.0",
49
"gatsby-transformer-yaml": "^5.12.0",
@@ -56,7 +55,6 @@
55
"react-addons-text-content": "^0.0.4",
56
"react-dom": "^18.2.0",
57
"react-focus-on": "^3.9.1",
59
- "react-helmet": "^6.1.0",
58
"styled-components": "^5.3.11",
59
"styled-system": "^5.1.5"
60
},
src/components/nav-items.js
+3
-4
@@ -7,6 +7,7 @@ import * as getNav from '../util/get-nav'
7
import VisuallyHidden from './visually-hidden'
8
import headerNavItems from '../../content/header-nav.yml'
9
import usePage from '../hooks/use-page'
10
+import useSiteMetadata from '../hooks/use-site-metadata'
11
12
const NavItem = ({item, path, depth}) => {
13
const href = getNav.getLocation(item.url)
@@ -53,10 +54,8 @@ const ExternalNavItem = ({title, ...props}) => (
54
)
55
56
const Navigation = () => {
56
- const {
57
- location,
58
- pageContext: {repositoryUrl},
59
- } = usePage()
57
+ const {location} = usePage()
58
+ const {repositoryUrl} = useSiteMetadata()
59
const path = getNav.getLocation(location.pathname)
60
const items = getNav.getHierarchy(null, {path, hideVariants: true})
61
src/head.js
new
+27
@@ -0,0 +1,27 @@
1
+import React from 'react'
2
+import useSiteMetdata from './hooks/use-site-metadata'
3
+
4
+const buildTitle = (...parts) => [...new Set(parts.filter(Boolean))].join(' | ')
5
+
6
+export const Head = ({pageContext: {frontmatter = {}}}) => {
7
+ const siteMetadata = useSiteMetdata()
8
+
9
+ const title = buildTitle(frontmatter.title, siteMetadata.title)
10
+ const description = frontmatter.description || siteMetadata.description
11
+
12
+ return (
13
+ <>
14
+ <title>{title}</title>
15
+ <meta name="description" content={description} />
16
+ <meta property="og:title" content={title} />
17
+ <meta property="og:description" content={description} />
18
+ <meta property="og:image" content={siteMetadata.imageUrl} />
19
+ <meta property="twitter:card" content="summary_large_image" />
20
+ <html lang={siteMetadata.lang} />
21
+ </>
22
+ )
23
+}
24
+
25
+const PassThrough = ({children}) => children
26
+
27
+export default PassThrough
src/hooks/use-site-metadata.js
+1
@@ -10,6 +10,7 @@ function useSiteMetadata() {
10
description
11
lang
12
imageUrl
13
+ repositoryUrl
14
}
15
}
16
}
src/layout.js
+4
-4
@@ -10,7 +10,7 @@ import {SKIP_NAV} from './constants'
10
import useSiteMetadata from './hooks/use-site-metadata'
11
import usePage from './hooks/use-page'
12
13
-export const HeroLayout = ({children}) => {
13
+const HeroLayout = ({children}) => {
14
const {title, description} = useSiteMetadata()
15
16
return (
@@ -32,7 +32,7 @@ export const HeroLayout = ({children}) => {
32
)
33
}
34
35
-export const DefaultLayout = ({children}) => {
35
+const DefaultLayout = ({children}) => {
36
const {title, description} = usePage().frontmatter
37
return (
38
<Box
@@ -62,6 +62,6 @@ export const DefaultLayout = ({children}) => {
62
)
63
}
64
65
-const getLayout = ({path}) => ({'/': HeroLayout})[path] ?? DefaultLayout
65
+const Layout = ({children}) => React.createElement(usePage().path === '/' ? HeroLayout : DefaultLayout, null, children)
66
67
-export default getLayout
67
+export default Layout
src/page.js
+7
-31
@@ -2,34 +2,12 @@ import React from 'react'
2
import {BaseStyles, themeGet, Box} from '@primer/react'
3
import styled, {createGlobalStyle} from 'styled-components'
4
import {SKIP_NAV} from './constants'
5
-import {Helmet} from 'react-helmet'
5
import Slugger from 'github-slugger'
6
import Header from './components/header'
7
import Sidebar from './components/sidebar'
8
import Link from './components/link'
10
-import useSiteMetdata from './hooks/use-site-metadata'
11
-import usePage, {PageProvider} from './hooks/use-page'
12
-import getLayout from './layout'
13
-
14
-const Head = () => {
15
- const {frontmatter} = usePage()
16
- const siteMetadata = useSiteMetdata()
17
-
18
- const title = [frontmatter.title, siteMetadata.title].filter(Boolean).join(' | ')
19
- const description = frontmatter.description || siteMetadata.description
20
-
21
- return (
22
- <Helmet>
23
- <title>{title}</title>
24
- <meta name="description" content={description} />
25
- <meta property="og:title" content={title} />
26
- <meta property="og:description" content={description} />
27
- <meta property="og:image" content={siteMetadata.imageUrl} />
28
- <meta property="twitter:card" content="summary_large_image" />
29
- <html lang={siteMetadata.lang} />
30
- </Helmet>
31
- )
32
-}
9
+import {PageProvider} from './hooks/use-page'
10
+import Layout from './layout'
11
12
const SkipLinkBase = props => (
13
<Link
@@ -46,6 +24,10 @@ const SkipLinkBase = props => (
24
</Link>
25
)
26
27
+// The following rules are to ensure that the element
28
+// is visually hidden, unless it has focus. This is the recommended
29
+// way to hide content from:
30
+// https://webaim.org/techniques/css/invisiblecontent/#techniques
31
export const SkipLink = styled(SkipLinkBase)`
32
z-index: 20;
33
width: auto;
@@ -54,11 +36,6 @@ export const SkipLink = styled(SkipLinkBase)`
36
position: absolute;
37
overflow: hidden;
38
57
- // The following rules are to ensure that the element
58
- // is visually hidden, unless it has focus. This is the recommended
59
- // way to hide content from:
60
- // https://webaim.org/techniques/css/invisiblecontent/#techniques
61
-
39
&:not(:focus) {
40
clip: rect(1px, 1px, 1px, 1px);
41
clip-path: inset(50%);
@@ -90,13 +67,12 @@ const PageElement = ({element, props}) => {
67
<SkipLink />
68
<PageProvider value={page}>
69
<Box sx={{display: 'flex', flexDirection: 'column', minHeight: '100vh'}}>
93
- <Head />
70
<Header />
71
<Box sx={{zIndex: 0, display: 'flex', flex: '1 1 auto', flexDirection: 'row'}} role="main">
72
<Box sx={{display: ['none', null, null, 'block']}}>
73
<Sidebar />
74
</Box>
99
- {React.createElement(getLayout(page), {key: 'layout', ...props}, element)}
75
+ <Layout>{element}</Layout>
76
</Box>
77
</Box>
78
</PageProvider>