Skip to content

Commit

Permalink
Make sure all GraphQL reference links retains version (#46142)
Browse files Browse the repository at this point in the history
  • Loading branch information
peterbe authored Nov 15, 2023
1 parent ccd3073 commit 5ea0920
Show file tree
Hide file tree
Showing 9 changed files with 68 additions and 45 deletions.
44 changes: 30 additions & 14 deletions src/frame/components/Link.tsx
Original file line number Diff line number Diff line change
@@ -1,36 +1,52 @@
import { useRouter } from 'next/router'
import NextLink from 'next/link'
import { ComponentProps } from 'react'

import { DEFAULT_VERSION, useVersion } from 'src/versions/components/useVersion'

const { NODE_ENV } = process.env

type Props = { locale?: string; disableClientTransition?: boolean } & ComponentProps<'a'>
type Props = {
locale?: string
disableClientTransition?: boolean
makeAbsolute?: boolean
} & ComponentProps<'a'>
export function Link(props: Props) {
const { href, locale, disableClientTransition = false, ...restProps } = props
const {
href,
locale,
disableClientTransition = false,
makeAbsolute = false,
...restProps
} = props
const router = useRouter()
const { currentVersion } = useVersion()

if (!href && NODE_ENV !== 'production') {
console.warn('Missing href on Link')
}

const isExternal = href?.startsWith('http') || href?.startsWith('//')
let url = href || ''
const isExternal = url.startsWith('http') || url.startsWith('//')
if (makeAbsolute && !isExternal) {
url = `/${locale || router.locale}`
if (currentVersion !== DEFAULT_VERSION) {
url += `/${currentVersion}`
}
url += href
} else if (locale && !isExternal) {
url = `/${locale}${href}`
}

if (disableClientTransition) {
return (
/* eslint-disable-next-line jsx-a11y/anchor-has-content */
<a
href={locale ? `/${locale}${href}` : href}
rel={isExternal ? 'noopener' : ''}
{...restProps}
/>
<a href={url} rel={isExternal ? 'noopener' : ''} {...restProps} />
)
}

return (
<NextLink
href={locale ? `/${locale}${href}` : href || ''}
locale={locale || false}
passHref
legacyBehavior
>
<NextLink href={url} locale={locale || false} passHref legacyBehavior>
{/* eslint-disable-next-line jsx-a11y/anchor-has-content */}
<a rel={isExternal ? 'noopener' : ''} {...restProps} />
</NextLink>
Expand Down
5 changes: 1 addition & 4 deletions src/graphql/components/Interface.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from 'next/router'

import { Link } from 'src/frame/components/Link'
import { GraphqlItem } from './GraphqlItem'
import { Table } from './Table'
Expand All @@ -12,7 +10,6 @@ type Props = {
}

export function Interface({ item, objects }: Props) {
const { locale } = useRouter()
const { t } = useTranslation('graphql')
const heading = t('reference.implemented_by').replace('{{ GraphQLItemTitle }}', item.name)
const heading2 = t('reference.fields').replace('{{ GraphQLItemTitle }}', item.name)
Expand All @@ -29,7 +26,7 @@ export function Interface({ item, objects }: Props) {
{implementedBy.map((object) => (
<li key={`${item.id}-${item.name}-${object.href}-${object.name}`}>
<code>
<Link href={object.href} locale={locale}>
<Link href={object.href} makeAbsolute>
{object.name}
</Link>
</code>
Expand Down
5 changes: 1 addition & 4 deletions src/graphql/components/Mutation.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from 'next/router'

import { Link } from 'src/frame/components/Link'
import { GraphqlItem } from './GraphqlItem'
import { Notice } from './Notice'
Expand All @@ -13,7 +11,6 @@ type Props = {
}

export function Mutation({ item }: Props) {
const { locale } = useRouter()
const { t } = useTranslation('graphql')
const heading = t('reference.input_fields').replace('{{ GraphQLItemTitle }}', item.name)
const heading2 = t('reference.return_fields').replace('{{ GraphQLItemTitle }}', item.name)
Expand All @@ -26,7 +23,7 @@ export function Mutation({ item }: Props) {
<li>
<code>{input.name}</code> (
<code>
<Link href={input.href} locale={locale}>
<Link href={input.href} makeAbsolute>
{input.type}
</Link>
</code>
Expand Down
6 changes: 1 addition & 5 deletions src/graphql/components/Notice.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from 'next/router'

import { Link } from 'src/frame/components/Link'
import { useTranslation } from 'src/languages/components/useTranslation'
import type { GraphqlT } from './types'
Expand All @@ -10,8 +8,6 @@ type Props = {
}

export function Notice({ item, variant = 'preview' }: Props) {
const { locale } = useRouter()

const { t } = useTranslation('graphql')
const previewTitle =
variant === 'preview' ? t('reference.preview_notice') : t('reference.deprecation_notice')
Expand All @@ -24,7 +20,7 @@ export function Notice({ item, variant = 'preview' }: Props) {
{variant === 'preview' && item.preview ? (
<p>
<code>{item.name}</code> is available under the{' '}
<Link href={item.preview.href} locale={locale}>
<Link href={item.preview.href} makeAbsolute>
{item.preview.title}
</Link>
. {t('reference.preview_period')}
Expand Down
5 changes: 1 addition & 4 deletions src/graphql/components/Object.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from 'next/router'

import { Link } from 'src/frame/components/Link'
import { GraphqlItem } from './GraphqlItem'
import { Table } from './Table'
Expand All @@ -11,7 +9,6 @@ type Props = {
}

export function Object({ item }: Props) {
const { locale } = useRouter()
const { t } = useTranslation('graphql')
const heading1 = t('reference.implements').replace('{{ GraphQLItemTitle }}', item.name)
const heading2 = t('reference.fields').replace('{{ GraphQLItemTitle }}', item.name)
Expand All @@ -25,7 +22,7 @@ export function Object({ item }: Props) {
{item.implements.map((implement: ImplementsT) => (
<li key={`${implement.id}-${implement.href}-${implement.name}`}>
<code>
<Link href={implement.href} locale={locale}>
<Link href={implement.href} makeAbsolute>
{implement.name}
</Link>
</code>
Expand Down
5 changes: 1 addition & 4 deletions src/graphql/components/Query.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from 'next/router'

import { Link } from 'src/frame/components/Link'
import { GraphqlItem } from './GraphqlItem'
import { Table } from './Table'
Expand All @@ -11,15 +9,14 @@ type Props = {
}

export function Query({ item }: Props) {
const { locale } = useRouter()
const { t } = useTranslation('graphql')

return (
<GraphqlItem item={item} headingLevel={3}>
<div>
<p>
<b>{t('graphql.reference.type')}: </b>
<Link href={item.href} locale={locale}>
<Link href={item.href} makeAbsolute>
{item.type}
</Link>
</p>
Expand Down
8 changes: 2 additions & 6 deletions src/graphql/components/Table.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from 'next/router'

import { Link } from 'src/frame/components/Link'
import { Notice } from './Notice'
import { useTranslation } from 'src/languages/components/useTranslation'
Expand All @@ -10,8 +8,6 @@ type Props = {
}

export function Table({ fields }: Props) {
const { locale } = useRouter()

const { t } = useTranslation('graphql')
const tableName = t('reference.name')
const tableDescription = t('reference.description')
Expand All @@ -33,7 +29,7 @@ export function Table({ fields }: Props) {
<code>
<Link
href={field.href}
locale={locale}
makeAbsolute
aria-label={[field.name, field.type, 'type definition'].join(' ')}
>
{field.type}
Expand Down Expand Up @@ -80,7 +76,7 @@ export function Table({ fields }: Props) {
<p className="mt-2">
<code>{argument.name}</code> (
<code>
<Link href={argument.type.href} locale={locale}>
<Link href={argument.type.href} makeAbsolute>
{argument.type.name}
</Link>
</code>
Expand Down
5 changes: 1 addition & 4 deletions src/graphql/components/Union.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import { useRouter } from 'next/router'

import { Link } from 'src/frame/components/Link'
import { GraphqlItem } from './GraphqlItem'
import { useTranslation } from 'src/languages/components/useTranslation'
Expand All @@ -10,7 +8,6 @@ type Props = {
}

export function Union({ item }: Props) {
const { locale } = useRouter()
const { t } = useTranslation('graphql')
const heading = t('reference.possible_types').replace('{{ GraphQLItemTitle }}', item.name)

Expand All @@ -19,7 +16,7 @@ export function Union({ item }: Props) {
<ul>
{item.possibleTypes.map((type) => (
<li key={type.id}>
<Link href={type.href} locale={locale}>
<Link href={type.href} makeAbsolute>
<code>{type.name}</code>
</Link>
</li>
Expand Down
30 changes: 30 additions & 0 deletions src/graphql/tests/server-rendering.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
import { getDOM } from '#src/tests/helpers/e2etest.js'
import { loadPages } from '#src/frame/lib/page-data.js'

const pageList = await loadPages(undefined, ['en'])

describe('server rendering certain GraphQL pages', () => {
test('minitoc hrefs on breaking-changes match', async () => {
Expand All @@ -16,4 +19,31 @@ describe('server rendering certain GraphQL pages', () => {
}
expect.assertions(hrefs.length + 1)
})

const autogeneratedPages = pageList.filter(
(page) => page.autogenerated === 'graphql' && page.relativePath.includes('reference'),
)
const nonFPTPermalinks = autogeneratedPages
.map((page) =>
page.permalinks.find((permalink) => permalink.pageVersion !== 'free-pro-team@latest'),
)
.filter(Boolean)
const nonFPTPermalinksHrefs = nonFPTPermalinks.map((permalink) => {
return permalink.href
})

test.each(nonFPTPermalinksHrefs)(
'all links keep locale and version in %s',
async (permalinkHref) => {
const $ = await getDOM(permalinkHref)
const internalLinks = $('#article-contents a[href^="/"]')
const hrefs = internalLinks.map((i, link) => $(link).attr('href')).get()
const [, pageLocale, pageVersion] = permalinkHref.split('/')
for (const href of hrefs) {
const [, locale, version] = href.split('/')
expect(locale).toBe(pageLocale)
expect(version).toBe(pageVersion)
}
},
)
})

0 comments on commit 5ea0920

Please sign in to comment.