Skip to content

Commit 1fc8539

Browse files
committed
Use link component instead of catch links plugin
1 parent eca2fe6 commit 1fc8539

File tree

12 files changed

+127
-100
lines changed

12 files changed

+127
-100
lines changed

gatsby-config.js

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -63,11 +63,8 @@ module.exports = {
6363
DEV_SSR: !!process.env.DEV_SSR,
6464
},
6565
plugins: [
66-
{
67-
resolve: 'gatsby-plugin-styled-components',
68-
},
66+
'gatsby-plugin-styled-components',
6967
'gatsby-plugin-react-helmet',
70-
'gatsby-plugin-catch-links',
7168
'gatsby-transformer-yaml',
7269
{
7370
resolve: 'gatsby-plugin-mdx',

gatsby-node.js

Lines changed: 62 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
const path = require('path')
1+
const {resolve, join: _join, relative} = require('path')
2+
const join = (...paths) => _join(...paths).replace(/\\/g, '/')
23

3-
const DEV = process.env.NODE_ENV === 'development'
44
const SHOW_CONTRIBUTORS = false
55
const REPO = {
66
url: 'https://github.com/npm/documentation',
@@ -32,7 +32,7 @@ exports.onCreateWebpackConfig = ({actions}) => {
3232
actions.setWebpackConfig({
3333
resolve: {
3434
alias: {
35-
'~': path.resolve(__dirname, 'src/'),
35+
'~': resolve(__dirname, 'src/'),
3636
},
3737
extensions: ['.js'],
3838
},
@@ -61,8 +61,6 @@ exports.createSchemaCustomization = ({actions: {createTypes}}) => {
6161
}
6262

6363
exports.createPages = async ({graphql, actions}) => {
64-
const rootAbsolutePath = process.cwd()
65-
6664
const {data} = await graphql(`
6765
{
6866
allMdx {
@@ -96,82 +94,71 @@ exports.createPages = async ({graphql, actions}) => {
9694
`)
9795

9896
// Turn every MDX file into a page.
99-
return Promise.all(
100-
data.allMdx.nodes.map(async node => {
101-
const {
102-
id,
103-
frontmatter,
104-
internal: {contentFilePath},
105-
tableOfContents = {},
106-
} = node
97+
return Promise.all(data.allMdx.nodes.map(node => createPage(node, actions)))
98+
}
10799

108-
const pagePath = getPath(node)
109-
const relativePath = path.relative(rootAbsolutePath, contentFilePath)
110-
const editUrl = getEditUrl(REPO, relativePath, frontmatter)
100+
async function createPage(
101+
{
102+
id,
103+
internal: {contentFilePath},
104+
fields: {slug} = {},
105+
frontmatter = {},
106+
tableOfContents = {},
107+
parent: {relativeDirectory, name: parentName},
108+
},
109+
actions,
110+
) {
111+
// sites can programmatically override slug, that takes priority
112+
// then a slug specified in frontmatter
113+
// finally, we'll just use the path on disk
114+
const pagePath = slug ?? frontmatter.slug ?? join(relativeDirectory, parentName === 'index' ? '/' : parentName)
111115

112-
const contributors = SHOW_CONTRIBUTORS ? await fetchContributors(REPO, relativePath, frontmatter) : {}
116+
const relativePath = relative(process.cwd(), contentFilePath)
113117

114-
// Fix some old CLI pages which have mismatched headings at the top level.
115-
// All top level headings should be the same level.
116-
const toc = tableOfContents.items?.reduce((acc, item) => {
117-
if (!item.url && Array.isArray(item.items)) {
118-
acc.push(...item.items)
119-
} else {
120-
acc.push(item)
121-
}
122-
return acc
123-
}, [])
118+
const editUrl = getEditUrl(REPO, relativePath, frontmatter)
124119

125-
actions.createPage({
126-
path: pagePath,
127-
component: contentFilePath,
128-
context: {
129-
mdxId: id,
130-
editUrl,
131-
contributors,
132-
tableOfContents: toc,
133-
repositoryUrl: REPO.url,
134-
},
135-
})
136-
137-
if (!DEV) {
138-
for (const from of frontmatter.redirect_from ?? []) {
139-
actions.createRedirect({
140-
fromPath: from,
141-
toPath: `/${pagePath}`,
142-
isPermanent: true,
143-
redirectInBrowser: true,
144-
})
120+
const contributors = SHOW_CONTRIBUTORS ? await fetchContributors(REPO, relativePath, frontmatter) : {}
145121

146-
if (pagePath.startsWith('cli/') && !from.endsWith('index')) {
147-
actions.createRedirect({
148-
fromPath: `${from}.html`,
149-
toPath: `/${pagePath}`,
150-
isPermanent: true,
151-
redirectInBrowser: true,
152-
})
153-
}
154-
}
155-
}
156-
}),
157-
)
158-
}
122+
// Fix some old CLI pages which have mismatched headings at the top level.
123+
// All top level headings should be the same level.
124+
const toc = tableOfContents.items?.reduce((acc, item) => {
125+
if (!item.url && Array.isArray(item.items)) {
126+
acc.push(...item.items)
127+
} else {
128+
acc.push(item)
129+
}
130+
return acc
131+
}, [])
132+
133+
actions.createPage({
134+
path: pagePath,
135+
component: contentFilePath,
136+
context: {
137+
mdxId: id,
138+
editUrl,
139+
contributors,
140+
tableOfContents: toc,
141+
repositoryUrl: REPO.url,
142+
},
143+
})
159144

160-
function getPath(node) {
161-
// sites can programmatically override slug, that takes priority
162-
if (node.fields && node.fields.slug) {
163-
return node.fields.slug
164-
}
145+
for (const from of frontmatter.redirect_from ?? []) {
146+
actions.createRedirect({
147+
fromPath: from,
148+
toPath: `/${pagePath}`,
149+
isPermanent: true,
150+
redirectInBrowser: true,
151+
})
165152

166-
// then a slug specified in frontmatter
167-
if (node.frontmatter && node.frontmatter.slug) {
168-
return node.frontmatter.slug
153+
if (pagePath.startsWith('cli/') && !from.endsWith('index')) {
154+
actions.createRedirect({
155+
fromPath: `${from}.html`,
156+
toPath: `/${pagePath}`,
157+
isPermanent: true,
158+
redirectInBrowser: true,
159+
})
160+
}
169161
}
170-
171-
// finally, we'll just use the path on disk
172-
return path
173-
.join(node.parent.relativeDirectory, node.parent.name === 'index' ? '/' : node.parent.name)
174-
.replace(/\\/g, '/') // Windows paths to forward slashes
175162
}
176163

177164
function getGitHubData(repo, overrideData, filePath) {
@@ -204,8 +191,8 @@ function getEditUrl(repo, filePath, overrideData = {}) {
204191
return null
205192
}
206193

207-
const gh = getGitHubData(repo, overrideData, filePath)
208-
return `https://github.com/${gh.nwo}/edit/${gh.branch}/${gh.path}`
194+
const {nwo, branch, path} = getGitHubData(repo, overrideData, filePath)
195+
return `https://github.com/${nwo}/edit/${branch}/${path}`
209196
}
210197

211198
const CONTRIBUTOR_CACHE = new Map()

package.json

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
"framer-motion": "^10.16.4",
3838
"fuse.js": "^3.6.1",
3939
"gatsby": "^5.12.7",
40-
"gatsby-plugin-catch-links": "^5.12.0",
4140
"gatsby-plugin-manifest": "^5.12.1",
4241
"gatsby-plugin-mdx": "^5.12.1",
4342
"gatsby-plugin-meta-redirect": "^1.1.1",

src/components/contributors.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1-
import {Box, Avatar, Link, Text, Tooltip} from '@primer/react'
21
import React from 'react'
2+
import {Box, Avatar, Text, Tooltip} from '@primer/react'
3+
import Link from './link'
34

45
const months = [
56
'January',

src/components/header.js

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import React from 'react'
2-
import {Box, Link, ThemeProvider} from '@primer/react'
3-
import {Link as GatsbyLink} from 'gatsby'
2+
import {Box, ThemeProvider} from '@primer/react'
43
import styled from 'styled-components'
54
import MobileSearch from './mobile-search'
65
import NavDrawer from './nav-drawer'
76
import Search from './search'
7+
import Link from './link'
88
import useSearch from '../hooks/use-search'
99
import {HEADER_HEIGHT, HEADER_BAR, NPM_RED} from '../constants'
1010
import useSiteMetadata from '../hooks/use-site-metadata'
@@ -56,7 +56,6 @@ function Header() {
5656
>
5757
<Box sx={{display: 'flex', alignItems: 'center'}}>
5858
<Link
59-
as={GatsbyLink}
6059
to="/"
6160
sx={{
6261
mr: 4,

src/components/link.js

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React from 'react'
2+
import {Link as PrimerLink} from '@primer/react'
3+
import {Link as GatsbyLink} from 'gatsby'
4+
5+
const FALLBACK = `http://_${Math.random().toString().slice(2)}._${Math.random().toString().slice(2)}`
6+
7+
const getLocalPath = href => {
8+
if (!href || href.startsWith('#')) {
9+
return null
10+
}
11+
12+
try {
13+
const url = new URL(href, FALLBACK)
14+
if (url.host === 'docs.npmjs.com' || url.origin === FALLBACK) {
15+
return `${url.pathname}${url.search}${url.hash}`
16+
}
17+
} catch {
18+
// ignore errors which will just pass along all props to PrimerLink
19+
}
20+
21+
return null
22+
}
23+
24+
const GatsbyLinkWithoutSxProps = React.forwardRef(function GatsbyLinkWithoutSxProps(
25+
{sx, underline, hoverColor, muted, ...props},
26+
ref,
27+
) {
28+
return <GatsbyLink ref={ref} {...props} />
29+
})
30+
31+
const Link = React.forwardRef(function Link({to, href, ...props}, ref) {
32+
const localPath = getLocalPath(href)
33+
34+
if (to || localPath !== null) {
35+
return <PrimerLink ref={ref} as={GatsbyLinkWithoutSxProps} to={to || localPath} {...props} />
36+
}
37+
38+
return <PrimerLink ref={ref} href={href} {...props} />
39+
})
40+
41+
export default Link

src/components/nav-drawer.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import React from 'react'
2-
import {Button, Box, Link, ThemeProvider} from '@primer/react'
2+
import {Button, Box, ThemeProvider} from '@primer/react'
33
import {XIcon, ThreeBarsIcon} from '@primer/octicons-react'
4-
import {Link as GatsbyLink} from 'gatsby'
4+
import Link from './link'
55
import Drawer from './drawer'
66
import NavItems from './nav-items'
77
import useSiteMetadata from '../hooks/use-site-metadata'
@@ -71,7 +71,7 @@ function NavDrawer() {
7171
display: 'flex',
7272
}}
7373
>
74-
<Link as={GatsbyLink} to="/" sx={{display: 'inline-block', color: 'inherit'}}>
74+
<Link to="/" sx={{display: 'inline-block', color: 'inherit'}}>
7575
{siteMetadata.title}
7676
</Link>
7777
<Button aria-label="Close" onClick={setClose}>

src/components/nav-items.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
import React from 'react'
22
import {Box} from '@primer/react'
3-
import {Link as GatsbyLink} from 'gatsby'
43
import {NavList} from '@primer/react/drafts'
54
import {LinkExternalIcon} from '@primer/octicons-react'
5+
import Link from './link'
66
import * as getNav from '../util/get-nav'
77
import VisuallyHidden from './visually-hidden'
88
import headerNavItems from '../../content/header-nav.yml'
@@ -15,7 +15,7 @@ const NavItem = ({item, path, depth}) => {
1515

1616
return (
1717
<NavList.Item
18-
as={GatsbyLink}
18+
as={Link}
1919
to={href}
2020
defaultOpen={items && isCurrent}
2121
aria-current={isCurrent ? 'page' : null}

src/components/page-footer.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import React from 'react'
2-
import {Box, Link, Octicon} from '@primer/react'
2+
import {Box, Octicon} from '@primer/react'
33
import {PencilIcon} from '@primer/octicons-react'
4+
import Link from './link'
45
import Contributors from './contributors'
56

67
function PageFooter({editUrl, contributors = {}}) {

src/mdx/index.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
import React from 'react'
2-
import {Box, Heading, themeGet, Text, Link as PrimerLink, Octicon} from '@primer/react'
2+
import {Box, Heading, themeGet, Text, Octicon} from '@primer/react'
3+
import {withPrefix} from 'gatsby'
34
import styled from 'styled-components'
45
import {variant} from 'styled-system'
5-
import {withPrefix} from 'gatsby'
66
import {LinkIcon} from '@primer/octicons-react'
77
import textContent from 'react-addons-text-content'
88
import {FULL_HEADER_HEIGHT} from '../constants'
99
import usePage from '../hooks/use-page'
10+
import SiteLink from '../components/link'
1011

1112
export {default as Code} from './code'
1213
export {default as Index} from './nav-hierarchy'
@@ -18,7 +19,7 @@ const required = (prop, name) => {
1819
return prop
1920
}
2021

21-
export const Link = props => <PrimerLink underline {...props} />
22+
export const Link = props => <SiteLink underline {...props} />
2223

2324
const StyledHeading = styled(Heading)`
2425
margin-top: ${themeGet('space.4')};
@@ -40,7 +41,7 @@ const StyledHeading = styled(Heading)`
4041

4142
const HeaderLink = ({autolink, children, ...props}) =>
4243
autolink ? (
43-
<PrimerLink
44+
<SiteLink
4445
{...props}
4546
sx={{
4647
color: 'inherit',
@@ -60,7 +61,7 @@ const HeaderLink = ({autolink, children, ...props}) =>
6061
verticalAlign: 'middle !important',
6162
}}
6263
/>
63-
</PrimerLink>
64+
</SiteLink>
6465
) : (
6566
children
6667
)

0 commit comments

Comments
 (0)