Skip to content

Commit cacfb31

Browse files
authored
fix: fixed localized links and next links redirection (#5474)
1 parent fabef79 commit cacfb31

File tree

15 files changed

+1034
-978
lines changed

15 files changed

+1034
-978
lines changed

Diff for: .eslintrc

-19
Original file line numberDiff line numberDiff line change
@@ -6,25 +6,6 @@
66
"plugin:storybook/recommended"
77
],
88
"overrides": [
9-
{
10-
"files": ["**/*.{mjs,js,ts,tsx}"],
11-
"rules": {
12-
"import/order": [
13-
"warn",
14-
{
15-
"groups": [
16-
"builtin",
17-
"external",
18-
"internal",
19-
"sibling",
20-
"parent",
21-
"index",
22-
"type"
23-
]
24-
}
25-
]
26-
}
27-
},
289
{
2910
"files": ["**/*.ts?(x)"],
3011
"plugins": ["@typescript-eslint"],

Diff for: components/Common/ActiveLocalizedLink/index.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ import { useRouter } from 'next/router';
22
import { useState, useEffect, type FC } from 'react';
33
import classNames from 'classnames';
44
import LocalizedLink from '../../LocalizedLink';
5-
import type { LinkProps } from 'next/link';
6-
import type { PropsWithChildren } from 'react';
5+
import type Link from 'next/link';
6+
import type { ComponentProps } from 'react';
77

8-
type ActiveLocalizedLinkProps = PropsWithChildren<
9-
LinkProps & { className?: string; activeClassName: string }
10-
>;
8+
type ActiveLocalizedLinkProps = ComponentProps<typeof Link> & {
9+
activeClassName: string;
10+
};
1111

1212
const ActiveLocalizedLink: FC<ActiveLocalizedLinkProps> = ({
1313
children,

Diff for: components/Downloads/DownloadReleasesTable.tsx

+1-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import { FormattedMessage } from 'react-intl';
2-
import Link from 'next/link';
32
import { getNodejsChangelog } from '../../util/getNodeJsChangelog';
43
import { getNodeApiLink } from '../../util/getNodeApiLink';
54
import { useNodeReleases } from '../../hooks/useNodeReleases';
@@ -18,7 +17,7 @@ const DownloadReleasesTable: FC = () => {
1817
<td>V8</td>
1918
<td>npm</td>
2019
<td>
21-
NODE_MODULE_VERSION<Link href="#ref-1">[1]</Link>
20+
NODE_MODULE_VERSION<a href="#ref-1">[1]</a>
2221
<span id="backref-1"></span>
2322
</td>
2423
<td></td>

Diff for: components/Downloads/DownloadToggle/index.module.scss

+4-2
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@
2828
background: var(--black0);
2929
border: none;
3030
border-radius: 32px;
31-
box-shadow: inset 1px -1px 1px rgba(0, 0, 0, 0.08),
31+
box-shadow:
32+
inset 1px -1px 1px rgba(0, 0, 0, 0.08),
3233
inset 0px 1px 2px rgba(0, 0, 0, 0.08);
3334
box-sizing: border-box;
3435
color: var(--black7);
@@ -44,7 +45,8 @@
4445
width: 133px;
4546

4647
&.current {
47-
box-shadow: inset 1px -1px 1px rgba(0, 0, 0, 0.08),
48+
box-shadow:
49+
inset 1px -1px 1px rgba(0, 0, 0, 0.08),
4850
inset 0px 1px 2px rgba(0, 0, 0, 0.08);
4951
margin-left: -30px;
5052
}

Diff for: components/Home/Banner.tsx

+2-3
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,3 @@
1-
import Link from 'next/link';
21
import { useSiteConfig } from '../../hooks/useSiteConfig';
32
import { dateIsBetween } from '../../util/dateIsBetween';
43

@@ -17,14 +16,14 @@ const Banner = () => {
1716
if (showBanner && indexBanner.text) {
1817
return (
1918
<p className="home-version home-version-banner">
20-
<Link href={indexBanner.link}>{indexBanner.text}</Link>
19+
<a href={indexBanner.link}>{indexBanner.text}</a>
2120
</p>
2221
);
2322
}
2423

2524
if (showBanner && indexBanner.html) {
2625
return (
27-
<Link
26+
<a
2827
href={indexBanner.link}
2928
dangerouslySetInnerHTML={{ __html: indexBanner.html }}
3029
/>

Diff for: components/Home/HomeDownloadButton.tsx

+7-6
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ const HomeDownloadButton: FC<NodeRelease> = ({
2121
const nodeDownloadLink = downloadUrlByOS(versionWithPrefix, os, bitness);
2222
const nodeApiLink = `https://nodejs.org/dist/latest-v${major}.x/docs/api/`;
2323
const nodeAllDownloadsLink = `/download${isLts ? '/' : '/current'}`;
24-
const nodeDownloadTitle =
25-
`${labels?.download} ${version}` +
26-
` ${labels?.[isLts ? 'lts' : 'current']}`;
24+
25+
const nodeDownloadTitle = `${labels?.download} ${version} ${labels?.[
26+
isLts ? 'lts' : 'current'
27+
]}`;
2728

2829
return (
2930
<div className="home-downloadblock">
@@ -44,12 +45,12 @@ const HomeDownloadButton: FC<NodeRelease> = ({
4445
</LocalizedLink>
4546
</li>
4647
<li>
47-
<LocalizedLink href={getNodejsChangelog(versionWithPrefix)}>
48+
<a href={getNodejsChangelog(versionWithPrefix)}>
4849
{labels?.changelog}
49-
</LocalizedLink>
50+
</a>
5051
</li>
5152
<li>
52-
<LocalizedLink href={nodeApiLink}>{labels?.api}</LocalizedLink>
53+
<a href={nodeApiLink}>{labels?.api}</a>
5354
</li>
5455
</ul>
5556
</div>

Diff for: components/Learn/PreviousNextLink/__snapshots__/index.stories.tsx.snap

+4-4
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ exports[`Learn/PreviousNextLink Default smoke-test 1`] = `
44
<ul class="PreviousNextLink_prevNextLink__9SAYu">
55
<li>
66
<a rel="prev"
7-
href="/previous"
7+
href="/en/previous"
88
>
99
<svg stroke="currentColor"
1010
fill="currentColor"
@@ -23,7 +23,7 @@ exports[`Learn/PreviousNextLink Default smoke-test 1`] = `
2323
</li>
2424
<li>
2525
<a rel="next"
26-
href="/next"
26+
href="/en/next"
2727
>
2828
NEXT
2929
<svg stroke="currentColor"
@@ -47,7 +47,7 @@ exports[`Learn/PreviousNextLink WithoutNext smoke-test 1`] = `
4747
<ul class="PreviousNextLink_prevNextLink__9SAYu">
4848
<li>
4949
<a rel="prev"
50-
href="/previous"
50+
href="/en/previous"
5151
>
5252
<svg stroke="currentColor"
5353
fill="currentColor"
@@ -75,7 +75,7 @@ exports[`Learn/PreviousNextLink WithoutPrevious smoke-test 1`] = `
7575
</li>
7676
<li>
7777
<a rel="next"
78-
href="/next"
78+
href="/en/next"
7979
>
8080
NEXT
8181
<svg stroke="currentColor"

Diff for: components/Learn/PreviousNextLink/__tests__/index.test.tsx

+13-4
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,15 @@ import { render, screen } from '@testing-library/react';
22
import { IntlProvider } from 'react-intl';
33
import PrevNextLink from '..';
44

5+
jest.mock('next/router', () => ({
6+
useRouter() {
7+
return {
8+
isReady: true,
9+
asPath: '/link',
10+
};
11+
},
12+
}));
13+
514
describe('PrevNextLink component', () => {
615
test('renders nothing if neither previous nor next are provided', () => {
716
render(<PrevNextLink />);
@@ -17,7 +26,7 @@ describe('PrevNextLink component', () => {
1726
</IntlProvider>
1827
);
1928
const link = screen.getByRole('link');
20-
expect(link).toHaveAttribute('href', previous.slug);
29+
expect(link).toHaveAttribute('href', `/en${previous.slug}`);
2130
});
2231

2332
test('renders next link if next is provided', () => {
@@ -28,7 +37,7 @@ describe('PrevNextLink component', () => {
2837
</IntlProvider>
2938
);
3039
const link = screen.getByRole('link');
31-
expect(link).toHaveAttribute('href', next.slug);
40+
expect(link).toHaveAttribute('href', `/en${next.slug}`);
3241
});
3342

3443
test('renders both previous and next links if both are provided', () => {
@@ -40,7 +49,7 @@ describe('PrevNextLink component', () => {
4049
</IntlProvider>
4150
);
4251
const links = screen.getAllByRole('link');
43-
expect(links[0]).toHaveAttribute('href', previous.slug);
44-
expect(links[1]).toHaveAttribute('href', next.slug);
52+
expect(links[0]).toHaveAttribute('href', `/en${previous.slug}`);
53+
expect(links[1]).toHaveAttribute('href', `/en${next.slug}`);
4554
});
4655
});

Diff for: components/Learn/PreviousNextLink/index.tsx

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
import Link from 'next/link';
21
import { FaAngleDoubleLeft, FaAngleDoubleRight } from 'react-icons/fa';
32
import { FormattedMessage } from 'react-intl';
4-
import styles from './index.module.scss';
3+
import LocalizedLink from '../../LocalizedLink';
54
import type { LinkInfo } from '../../../types';
65
import type { FC } from 'react';
76

7+
import styles from './index.module.scss';
8+
89
type PreviousNextLinkProps = {
910
previous?: LinkInfo;
1011
next?: LinkInfo;
@@ -19,18 +20,18 @@ const PreviousNextLink: FC<PreviousNextLinkProps> = ({ previous, next }) => {
1920
<ul className={styles.prevNextLink}>
2021
<li>
2122
{previous && (
22-
<Link href={previous.slug} rel="prev">
23+
<LocalizedLink href={previous.slug} rel="prev">
2324
<FaAngleDoubleLeft size="1em" style={{ marginRight: '5px' }} />
2425
<FormattedMessage id="components.learn.previousNextLink.previous" />
25-
</Link>
26+
</LocalizedLink>
2627
)}
2728
</li>
2829
<li>
2930
{next && (
30-
<Link href={next.slug} rel="next">
31+
<LocalizedLink href={next.slug} rel="next">
3132
<FormattedMessage id="components.learn.previousNextLink.next" />
3233
<FaAngleDoubleRight style={{ marginLeft: '5px' }} />
33-
</Link>
34+
</LocalizedLink>
3435
)}
3536
</li>
3637
</ul>

Diff for: components/LocalizedLink.tsx

+24-10
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,41 @@ import { useLocale } from '../hooks/useLocale';
44
import { linkWithLocale } from '../util/linkWithLocale';
55
import type { FC, ComponentProps } from 'react';
66

7+
// This is a wrapper on HTML's `a` tag
8+
const HtmlLink: FC<JSX.IntrinsicElements['a']> = ({ children, ...extra }) => (
9+
<a {...extra}>{children}</a>
10+
);
11+
12+
// This is Next.js's Link Component but with pre-fetch disabled
13+
const NextLink: FC<ComponentProps<typeof Link>> = ({ children, ...extra }) => (
14+
<Link {...extra} prefetch={false}>
15+
{children}
16+
</Link>
17+
);
18+
719
const LocalizedLink: FC<ComponentProps<typeof Link>> = ({
820
href,
921
children,
1022
...extra
1123
}) => {
1224
const { currentLocale } = useLocale();
1325

14-
const localizedUrl = linkWithLocale(currentLocale.code);
26+
const { Component, finalHref } = useMemo(() => {
27+
if (/^https?:\/\//.test(href.toString())) {
28+
return { Component: HtmlLink, finalHref: href.toString() };
29+
}
1530

16-
const finalHref = useMemo(
17-
() =>
18-
/^https?:\/\//.test(href.toString())
19-
? href.toString()
20-
: localizedUrl(href),
21-
[href, localizedUrl]
22-
);
31+
const addLocaleToHref = linkWithLocale(currentLocale.code);
32+
33+
return { Component: NextLink, finalHref: addLocaleToHref(href) };
34+
// We only need to check if the toString() variant of URL has changed
35+
// eslint-disable-next-line react-hooks/exhaustive-deps
36+
}, [currentLocale.code, href.toString()]);
2337

2438
return (
25-
<Link {...extra} href={finalHref}>
39+
<Component {...extra} href={finalHref}>
2640
{children}
27-
</Link>
41+
</Component>
2842
);
2943
};
3044

Diff for: components/Sections/NewHeader/__snapshots__/index.stories.tsx.snap

+1-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ exports[`Sections/NewHeader Default smoke-test 1`] = `
77
<div class="NewHeader_container__tyM2Y">
88
<div class="NewHeader_startWrapper__teZG4">
99
<a aria-label="Homepage"
10-
href="/"
10+
href="/en"
1111
>
1212
<div class="NewHeader_logo__mB_8v">
1313
<div>

Diff for: components/Sections/NewHeader/index.tsx

+5-4
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,19 @@
11
import { FormattedMessage } from 'react-intl';
22
import Image from 'next/image';
3-
import Link from 'next/link';
43
import { FaGithub } from 'react-icons/fa';
5-
import styles from './index.module.scss';
4+
import LocalizedLink from '../../LocalizedLink';
65
import ActiveLocalizedLink from '../../Common/ActiveLocalizedLink';
76
import DarkModeToggle from '../../Common/DarkModeToggle';
87
import LanguageSelector from '../../Common/LanguageSelector';
98
import type { FC } from 'react';
109

10+
import styles from './index.module.scss';
11+
1112
const Header: FC = () => (
1213
<nav aria-label="Primary" className={styles.header}>
1314
<div className={styles.container}>
1415
<div className={styles.startWrapper}>
15-
<Link href="/" aria-label="Homepage">
16+
<LocalizedLink href="/" aria-label="Homepage">
1617
<div className={styles.logo}>
1718
<div>
1819
<Image
@@ -33,7 +34,7 @@ const Header: FC = () => (
3334
/>
3435
</div>
3536
</div>
36-
</Link>
37+
</LocalizedLink>
3738
</div>
3839

3940
<ul className={styles.tabs}>

0 commit comments

Comments
 (0)