+1
-1
.storybook/preview.tsx
+1
-1
.storybook/preview.tsx
-3
README.md
-3
README.md
+1
-3
app/[locale]/[[...path]]/page.tsx
+1
-3
app/[locale]/[[...path]]/page.tsx
···
76
76
// Gets the current full pathname for a given path
77
77
const pathname = dynamicRouter.getPathname(path);
78
78
79
-
// @todo: once removed the legacy layouts remove the any casting
80
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
81
-
const staticGeneratedLayout = DYNAMIC_ROUTES.get(pathname) as any;
79
+
const staticGeneratedLayout = DYNAMIC_ROUTES.get(pathname);
82
80
83
81
// If the current patname is a statically generated route
84
82
// it means it does not have a Markdown file nor exists under the filesystem
+2
-16
app/[locale]/error.tsx
+2
-16
app/[locale]/error.tsx
···
4
4
import { captureException } from '@sentry/nextjs';
5
5
import { useTranslations } from 'next-intl';
6
6
import type { FC } from 'react';
7
-
import { useMemo } from 'react';
8
7
9
8
import Button from '@/components/Common/Button';
10
-
import CenteredLayout from '@/layouts/New/Centered';
11
-
import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
12
-
13
-
/** @deprecated remove legacy component when website redesign is done */
14
-
const LegacyErrorPage: FC<{ error: Error }> = ({ error }) => {
15
-
useMemo(() => captureException(error), [error]);
16
-
17
-
return (
18
-
<div className="container">
19
-
<h2>500: Internal Server Error</h2>
20
-
<h3>This Page has thrown a non-recoverable Error</h3>
21
-
</div>
22
-
);
23
-
};
9
+
import CenteredLayout from '@/layouts/Centered';
24
10
25
11
const ErrorPage: FC<{ error: Error }> = ({ error }) => {
26
12
captureException(error);
···
47
33
);
48
34
};
49
35
50
-
export default ENABLE_WEBSITE_REDESIGN ? ErrorPage : LegacyErrorPage;
36
+
export default ErrorPage;
+6
-19
app/[locale]/layout.tsx
+6
-19
app/[locale]/layout.tsx
···
4
4
import { getLocale } from 'next-intl/server';
5
5
import type { FC, PropsWithChildren } from 'react';
6
6
7
-
import LegacyBaseLayout from '@/layouts/BaseLayout';
8
-
import NewBaseLayout from '@/layouts/New/Base';
9
-
import { ENABLE_WEBSITE_REDESIGN, VERCEL_ENV } from '@/next.constants.mjs';
10
-
import { IBM_PLEX_MONO, OPEN_SANS, SOURCE_SANS } from '@/next.fonts';
7
+
import BaseLayout from '@/layouts/Base';
8
+
import { VERCEL_ENV } from '@/next.constants.mjs';
9
+
import { IBM_PLEX_MONO, OPEN_SANS } from '@/next.fonts';
11
10
import { availableLocalesMap, defaultLocale } from '@/next.locales.mjs';
12
11
import { LocaleProvider } from '@/providers/localeProvider';
13
12
import { ThemeProvider } from '@/providers/themeProvider';
14
13
15
-
// Uses a WebPack/TurboPack Alias for resolving Global Styles
16
-
// @deprecated remove when website redesign is done
17
-
// eslint-disable-next-line import/no-unresolved
18
-
import 'globalStyles';
14
+
import '@/styles/index.css';
19
15
20
-
// Defines the App Fonts based on being on Website Redesign or not
21
-
// @deprecated remove when website redesign is done
22
-
const fontClasses = classNames(IBM_PLEX_MONO.variable, {
23
-
[SOURCE_SANS.className]: !ENABLE_WEBSITE_REDESIGN,
24
-
[OPEN_SANS.variable]: ENABLE_WEBSITE_REDESIGN,
25
-
});
26
-
27
-
// Defines the Base Layout based on being on Website Redesign or not
28
-
// @deprecated remove when website redesign is done
29
-
const AppLayout = ENABLE_WEBSITE_REDESIGN ? NewBaseLayout : LegacyBaseLayout;
16
+
const fontClasses = classNames(IBM_PLEX_MONO.variable, OPEN_SANS.variable);
30
17
31
18
const RootLayout: FC<PropsWithChildren> = async ({ children }) => {
32
19
const locale = await getLocale();
···
38
25
<body suppressHydrationWarning>
39
26
<LocaleProvider>
40
27
<ThemeProvider>
41
-
<AppLayout>{children}</AppLayout>
28
+
<BaseLayout>{children}</BaseLayout>
42
29
</ThemeProvider>
43
30
</LocaleProvider>
44
31
+2
-15
app/[locale]/not-found.tsx
+2
-15
app/[locale]/not-found.tsx
···
5
5
import type { FC } from 'react';
6
6
7
7
import Button from '@/components/Common/Button';
8
-
import CenteredLayout from '@/layouts/New/Centered';
9
-
import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
10
-
11
-
/** @deprecated remove legacy component when website redesign is done */
12
-
const LegacyNotFoundPage: FC = () => {
13
-
const t = useTranslations();
14
-
15
-
return (
16
-
<div className="container">
17
-
<h2>{t('pages.404.title')}</h2>
18
-
<h3>{t('pages.404.description')}</h3>
19
-
</div>
20
-
);
21
-
};
8
+
import CenteredLayout from '@/layouts/Centered';
22
9
23
10
const NotFoundPage: FC = () => {
24
11
const t = useTranslations();
···
42
29
);
43
30
};
44
31
45
-
export default ENABLE_WEBSITE_REDESIGN ? NotFoundPage : LegacyNotFoundPage;
32
+
export default NotFoundPage;
+3
-21
app/global-error.tsx
+3
-21
app/global-error.tsx
···
2
2
3
3
import { ArrowRightIcon } from '@heroicons/react/24/solid';
4
4
import { captureException } from '@sentry/nextjs';
5
-
import ErrorComponent from 'next/error';
6
5
import type { FC } from 'react';
7
-
import { useMemo } from 'react';
8
6
9
7
import Button from '@/components/Common/Button';
10
-
import BaseLayout from '@/layouts/BaseLayout';
11
-
import CenteredLayout from '@/layouts/New/Centered';
12
-
import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
13
-
14
-
/** @deprecated remove legacy component when website redesign is done */
15
-
const LegacyGlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
16
-
useMemo(() => captureException(error), [error]);
17
-
18
-
return (
19
-
<html>
20
-
<body>
21
-
<ErrorComponent statusCode={500} />
22
-
</body>
23
-
</html>
24
-
);
25
-
};
8
+
import BaseLayout from '@/layouts/Base';
9
+
import CenteredLayout from '@/layouts/Centered';
26
10
27
11
const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
28
12
captureException(error);
···
52
36
);
53
37
};
54
38
55
-
export default ENABLE_WEBSITE_REDESIGN
56
-
? GlobalErrorPage
57
-
: LegacyGlobalErrorPage;
39
+
export default GlobalErrorPage;
+1
-5
components/Common/CodeBox/index.tsx
+1
-5
components/Common/CodeBox/index.tsx
···
10
10
11
11
import Button from '@/components/Common/Button';
12
12
import { useCopyToClipboard, useNotification } from '@/hooks';
13
-
import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
14
13
15
14
import styles from './index.module.css';
16
15
···
69
68
const CodeBox: FC<PropsWithChildren<CodeBoxProps>> = ({
70
69
children,
71
70
language,
72
-
// For now we only want to render the Copy Button by default
73
-
// if the Website Redesign is Enabled
74
-
// @todo remove this check once we migrate to website redesign
75
-
showCopyButton = ENABLE_WEBSITE_REDESIGN,
71
+
showCopyButton = true,
76
72
}) => {
77
73
const ref = useRef<HTMLPreElement>(null);
78
74
+1
components/Common/CrossLink/index.module.css
+1
components/Common/CrossLink/index.module.css
+1
-1
components/Common/Search/States/WithSearchResult.tsx
+1
-1
components/Common/Search/States/WithSearchResult.tsx
···
15
15
};
16
16
17
17
export const WithSearchResult: FC<SearchResultProps> = props => {
18
-
const isAPIResult = props.hit.document.siteSection.toLowerCase() === 'api';
18
+
const isAPIResult = props.hit.document.siteSection.toLowerCase() === 'docs';
19
19
const basePath = isAPIResult ? BASE_URL : '';
20
20
const path = `${basePath}/${props.hit.document.path}`;
21
21
+3
-6
components/Common/Search/index.module.css
+3
-6
components/Common/Search/index.module.css
···
2
2
@apply relative
3
3
w-52
4
4
rounded-md
5
-
bg-neutral-100
5
+
bg-neutral-200
6
6
py-2
7
7
pl-9
8
8
pr-4
9
9
text-left
10
10
text-sm
11
11
text-neutral-700
12
-
transition-colors
13
-
duration-200
14
-
ease-in-out
15
-
hover:bg-neutral-200
16
-
hover:text-neutral-800
12
+
hover:bg-neutral-300
13
+
hover:text-neutral-900
17
14
dark:bg-neutral-900
18
15
dark:text-neutral-600
19
16
dark:hover:bg-neutral-800
+2
components/Common/Search/index.tsx
+2
components/Common/Search/index.tsx
-36
components/Downloads/DownloadList.tsx
-36
components/Downloads/DownloadList.tsx
···
1
-
import { useTranslations } from 'next-intl';
2
-
import type { FC } from 'react';
3
-
4
-
import Link from '@/components/Link';
5
-
import { useSiteNavigation } from '@/hooks/server';
6
-
import type { NodeRelease } from '@/types';
7
-
8
-
const DownloadList: FC<NodeRelease> = ({ versionWithPrefix }) => {
9
-
const t = useTranslations();
10
-
11
-
const { getSideNavigation } = useSiteNavigation();
12
-
13
-
const [[, downloadNavigationItems]] = getSideNavigation(['download'], {
14
-
shaSums: { nodeVersion: versionWithPrefix },
15
-
allDownloads: { nodeVersion: versionWithPrefix },
16
-
});
17
-
18
-
return (
19
-
<section>
20
-
<ul>
21
-
{downloadNavigationItems.items.map(([key, { label, link }]) => (
22
-
<li key={key}>
23
-
<Link href={link}>{label}</Link>
24
-
{key === 'shaSums' && (
25
-
<a href="https://github.com/nodejs/node#verifying-binaries">
26
-
{t('components.downloadList.links.shaSums.howToVerify')}
27
-
</a>
28
-
)}
29
-
</li>
30
-
))}
31
-
</ul>
32
-
</section>
33
-
);
34
-
};
35
-
36
-
export default DownloadList;
-254
components/Downloads/PrimaryDownloadMatrix.tsx
-254
components/Downloads/PrimaryDownloadMatrix.tsx
···
1
-
'use client';
2
-
3
-
import classNames from 'classnames';
4
-
import type { FC } from 'react';
5
-
import semVer from 'semver';
6
-
7
-
import Link from '@/components/Link';
8
-
import WithCurrentOS from '@/components/withCurrentOS';
9
-
import { useClientContext } from '@/hooks';
10
-
import { DIST_URL } from '@/next.constants.mjs';
11
-
import type { NodeRelease } from '@/types';
12
-
13
-
// @TODO: Legacy Component to be removed in the Website Redesign
14
-
const PrimaryDownloadMatrix: FC<NodeRelease> = ({
15
-
version,
16
-
versionWithPrefix,
17
-
isLts,
18
-
npm,
19
-
}) => {
20
-
const {
21
-
frontmatter: { downloads },
22
-
} = useClientContext();
23
-
24
-
const hasWindowsArm64 = semVer.satisfies(version, '>= 19.9.0');
25
-
26
-
const getIsVersionClassName = (isCurrent: boolean) =>
27
-
classNames({ 'is-version': isCurrent });
28
-
29
-
return (
30
-
<section>
31
-
<p className="color-lightgray">
32
-
{downloads.currentVersion}: <strong>{version}</strong> (
33
-
{downloads.includes || 'includes'} npm {npm})
34
-
</p>
35
-
<p>{downloads.intro}</p>
36
-
37
-
<div className="download-hero full-width">
38
-
<ul className="no-padding download-version-toggle">
39
-
<li>
40
-
<Link
41
-
className={getIsVersionClassName(isLts)}
42
-
href="/download/"
43
-
title={`${downloads['display-hint']} ${downloads.lts}`}
44
-
>
45
-
<div className="title">{downloads.lts}</div>
46
-
<div className="tag">{downloads['tagline-lts']}</div>
47
-
</Link>
48
-
</li>
49
-
<li>
50
-
<Link
51
-
className={getIsVersionClassName(!isLts)}
52
-
href="/download/current"
53
-
title={`${downloads['display-hint']} ${downloads.current}`}
54
-
>
55
-
<div className="title">{downloads.current}</div>
56
-
<div className="tag">{downloads['tagline-current']}</div>
57
-
</Link>
58
-
</li>
59
-
</ul>
60
-
<ul className="no-padding download-platform">
61
-
<li>
62
-
<WithCurrentOS>
63
-
{({ currentOS }) => (
64
-
<a
65
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-x${currentOS.bitness}.msi`}
66
-
data-version={versionWithPrefix}
67
-
>
68
-
<svg
69
-
className="download-logo"
70
-
width="50"
71
-
height="50"
72
-
viewBox="0 0 50 50"
73
-
focusable="false"
74
-
>
75
-
<path d="M1.589 23.55L1.572 8.24l18.839-2.558V23.55zM23.55 5.225l25.112-3.654V23.55H23.55zM48.669 26.69l-.006 21.979-25.112-3.533V26.69zM20.41 44.736l-18.824-2.58-.001-15.466H20.41z" />
76
-
</svg>
77
-
{downloads.WindowsInstaller}
78
-
<p className="small color-lightgray">
79
-
node-{versionWithPrefix}-x{currentOS.bitness}.msi
80
-
</p>
81
-
</a>
82
-
)}
83
-
</WithCurrentOS>
84
-
</li>
85
-
<li>
86
-
<a
87
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.pkg`}
88
-
>
89
-
<svg
90
-
className="download-logo"
91
-
width="50"
92
-
height="50"
93
-
viewBox="0 0 50 50"
94
-
focusable="false"
95
-
>
96
-
<path d="M39.054 34.065q-1.093 3.504-3.448 7.009-3.617 5.495-7.205 5.495-1.374 0-3.925-.897-2.411-.897-4.233-.897-1.71 0-3.981.925-2.271.953-3.701.953-4.261 0-8.439-7.261Q.001 32.075.001 25.29q0-6.392 3.168-10.485 3.14-4.037 7.962-4.037 2.019 0 4.962.841 2.916.841 3.869.841 1.262 0 4.009-.953 2.86-.953 4.85-.953 3.336 0 5.972 1.822 1.458 1.009 2.916 2.804-2.215 1.878-3.196 3.308-1.822 2.635-1.822 5.803 0 3.476 1.934 6.252t4.43 3.533zM28.512 1.179q0 1.71-.813 3.813-.841 2.103-2.607 3.869-1.514 1.514-3.028 2.019-1.037.308-2.916.477.084-4.177 2.187-7.205 2.075-3 7.009-4.149.028.084.07.308t.07.308q0 .112.014.28t.014.28z" />
97
-
</svg>
98
-
{downloads.MacOSInstaller}
99
-
<p className="small color-lightgray">
100
-
node-{versionWithPrefix}.pkg
101
-
</p>
102
-
</a>
103
-
</li>
104
-
<li>
105
-
<a
106
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.tar.gz`}
107
-
>
108
-
<svg
109
-
className="download-logo"
110
-
width="50"
111
-
height="50"
112
-
viewBox="0 0 50 50"
113
-
focusable="false"
114
-
>
115
-
<path d="M25.03.934L.159 11.65l24.895 10.632 25.152-10.656L25.03.935zm1.02 22.686v25.686l24.188-11.483V13.345L26.05 23.62zM.001 37.824l24.27 11.483V23.621L.001 13.346v24.478z" />
116
-
</svg>
117
-
{downloads.SourceCode}
118
-
<p className="small color-lightgray">
119
-
node-{versionWithPrefix}.tar.gz
120
-
</p>
121
-
</a>
122
-
</li>
123
-
</ul>
124
-
</div>
125
-
126
-
<table className="download-matrix full-width">
127
-
<tbody>
128
-
<tr>
129
-
<th>{downloads.WindowsInstaller} (.msi)</th>
130
-
<td colSpan={hasWindowsArm64 ? 1 : 2}>
131
-
<a
132
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-x86.msi`}
133
-
>
134
-
32-bit
135
-
</a>
136
-
</td>
137
-
<td colSpan={2}>
138
-
<a
139
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-x64.msi`}
140
-
>
141
-
64-bit
142
-
</a>
143
-
</td>
144
-
{hasWindowsArm64 && (
145
-
<td colSpan={1}>
146
-
<a
147
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-arm64.msi`}
148
-
>
149
-
ARM64
150
-
</a>
151
-
</td>
152
-
)}
153
-
</tr>
154
-
155
-
<tr>
156
-
<th>{downloads.WindowsBinary} (.zip)</th>
157
-
<td colSpan={hasWindowsArm64 ? 1 : 2}>
158
-
<a
159
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-win-x86.zip`}
160
-
>
161
-
32-bit
162
-
</a>
163
-
</td>
164
-
<td colSpan={2}>
165
-
<a
166
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-win-x64.zip`}
167
-
>
168
-
64-bit
169
-
</a>
170
-
</td>
171
-
{hasWindowsArm64 && (
172
-
<td colSpan={1}>
173
-
<a
174
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-win-arm64.zip`}
175
-
>
176
-
ARM64
177
-
</a>
178
-
</td>
179
-
)}
180
-
</tr>
181
-
182
-
<tr>
183
-
<th>{downloads.MacOSInstaller} (.pkg)</th>
184
-
<td colSpan={4}>
185
-
<a
186
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.pkg`}
187
-
>
188
-
64-bit / ARM64
189
-
</a>
190
-
</td>
191
-
</tr>
192
-
<tr>
193
-
<th>{downloads.MacOSBinary} (.tar.gz)</th>
194
-
<td colSpan={2}>
195
-
<a
196
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-darwin-x64.tar.gz`}
197
-
>
198
-
64-bit
199
-
</a>
200
-
</td>
201
-
<td colSpan={2}>
202
-
<a
203
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-darwin-arm64.tar.gz`}
204
-
>
205
-
ARM64
206
-
</a>
207
-
</td>
208
-
</tr>
209
-
210
-
<tr>
211
-
<th>{downloads.LinuxBinaries} (x64)</th>
212
-
<td colSpan={4}>
213
-
<a
214
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-x64.tar.xz`}
215
-
>
216
-
64-bit
217
-
</a>
218
-
</td>
219
-
</tr>
220
-
<tr>
221
-
<th>{downloads.LinuxBinaries} (ARM)</th>
222
-
<td colSpan={2}>
223
-
<a
224
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-armv7l.tar.xz`}
225
-
>
226
-
ARMv7
227
-
</a>
228
-
</td>
229
-
<td colSpan={2}>
230
-
<a
231
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-arm64.tar.xz`}
232
-
>
233
-
ARMv8
234
-
</a>
235
-
</td>
236
-
</tr>
237
-
238
-
<tr>
239
-
<th>{downloads.SourceCode}</th>
240
-
<td colSpan={4}>
241
-
<a
242
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.tar.gz`}
243
-
>
244
-
node-{versionWithPrefix}.tar.gz
245
-
</a>
246
-
</td>
247
-
</tr>
248
-
</tbody>
249
-
</table>
250
-
</section>
251
-
);
252
-
};
253
-
254
-
export default PrimaryDownloadMatrix;
+8
-2
components/Downloads/Release/PlatformDropdown.tsx
+8
-2
components/Downloads/Release/PlatformDropdown.tsx
···
5
5
import type { FC } from 'react';
6
6
7
7
import Select from '@/components/Common/Select';
8
+
import Choco from '@/components/Icons/Platform/Choco';
8
9
import Docker from '@/components/Icons/Platform/Docker';
9
10
import Homebrew from '@/components/Icons/Platform/Homebrew';
10
11
import NVM from '@/components/Icons/Platform/NVM';
···
26
27
const disabledItems = [];
27
28
28
29
if (os === 'WIN') {
29
-
disabledItems.push('BREW');
30
+
disabledItems.push('BREW', 'NVM');
30
31
}
31
32
32
33
if (os === 'LINUX') {
33
-
disabledItems.push('DOCKER');
34
+
disabledItems.push('DOCKER', 'CHOCO');
35
+
}
36
+
37
+
if (os === 'MAC') {
38
+
disabledItems.push('CHOCO');
34
39
}
35
40
36
41
const releaseSupportsHomebrew = supportedHomebrewVersions.includes(
···
71
76
NVM: <NVM width={16} height={16} />,
72
77
BREW: <Homebrew width={16} height={16} />,
73
78
DOCKER: <Docker width={16} height={16} />,
79
+
CHOCO: <Choco width={16} height={16} />,
74
80
},
75
81
disabledItems,
76
82
})}
+5
-7
components/Downloads/Release/ReleaseCodeBox.tsx
+5
-7
components/Downloads/Release/ReleaseCodeBox.tsx
···
14
14
const memoizedShiki = getShiki();
15
15
16
16
const ReleaseCodeBox: FC = () => {
17
-
const {
18
-
platform,
19
-
os,
20
-
release: { major },
21
-
} = useContext(ReleaseContext);
17
+
const { platform, os, release } = useContext(ReleaseContext);
22
18
23
19
const [code, setCode] = useState('');
24
20
const t = useTranslations();
25
21
26
22
useEffect(() => {
27
-
const updatedCode = getNodeDownloadSnippet(major, os)[platform];
23
+
const updatedCode = getNodeDownloadSnippet(release, os)[platform];
28
24
// Docker and NVM support downloading tags/versions by their full release number
29
25
// but usually we should recommend users to download "major" versions
30
26
// since our Downlooad Buttons get the latest minor of a major, it does make sense
···
32
28
memoizedShiki
33
29
.then(shiki => highlightToHtml(shiki)(updatedCode, 'bash'))
34
30
.then(setCode);
35
-
}, [major, os, platform]);
31
+
// Only react when the specific release number changed
32
+
// eslint-disable-next-line react-hooks/exhaustive-deps
33
+
}, [release.versionWithPrefix, os, platform]);
36
34
37
35
return (
38
36
<div className="mb-2 mt-6 flex min-h-80 flex-col gap-2">
-73
components/Downloads/SecondaryDownloadMatrix.tsx
-73
components/Downloads/SecondaryDownloadMatrix.tsx
···
1
-
import type { FC } from 'react';
2
-
3
-
import DownloadList from '@/components/Downloads/DownloadList';
4
-
import WithNodeRelease from '@/components/withNodeRelease';
5
-
import { useClientContext } from '@/hooks/server';
6
-
import { DIST_URL } from '@/next.constants.mjs';
7
-
import type { NodeRelease } from '@/types';
8
-
9
-
// @TODO: Legacy Component to be removed in the Website Redesign
10
-
const SecondaryDownloadMatrix: FC<NodeRelease> = ({
11
-
versionWithPrefix,
12
-
status,
13
-
}) => {
14
-
const {
15
-
frontmatter: { additional },
16
-
} = useClientContext();
17
-
18
-
return (
19
-
<section>
20
-
<h2>{additional.headline}</h2>
21
-
<table className="download-matrix full-width">
22
-
<tbody>
23
-
<tr>
24
-
<th>{additional.DockerImage}</th>
25
-
<td>
26
-
<a href="https://hub.docker.com/_/node/">
27
-
{additional.officialDockerImage}
28
-
</a>
29
-
</td>
30
-
</tr>
31
-
32
-
<tr>
33
-
<th>{additional.LinuxPowerSystems}</th>
34
-
<td>
35
-
<a
36
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-ppc64le.tar.xz`}
37
-
>
38
-
64-bit
39
-
</a>
40
-
</td>
41
-
</tr>
42
-
43
-
<tr>
44
-
<th>{additional.LinuxSystemZ}</th>
45
-
<td>
46
-
<a
47
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-s390x.tar.xz`}
48
-
>
49
-
64-bit
50
-
</a>
51
-
</td>
52
-
</tr>
53
-
<tr>
54
-
<th>{additional.AIXPowerSystems}</th>
55
-
<td>
56
-
<a
57
-
href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-aix-ppc64.tar.gz`}
58
-
>
59
-
64-bit
60
-
</a>
61
-
</td>
62
-
</tr>
63
-
</tbody>
64
-
</table>
65
-
66
-
<WithNodeRelease status={status}>
67
-
{({ release }) => <DownloadList {...release} />}
68
-
</WithNodeRelease>
69
-
</section>
70
-
);
71
-
};
72
-
73
-
export default SecondaryDownloadMatrix;
-108
components/Header.tsx
-108
components/Header.tsx
···
1
-
'use client';
2
-
3
-
import Image from 'next/image';
4
-
import { useTranslations } from 'next-intl';
5
-
import { useTheme } from 'next-themes';
6
-
import type { FC, PropsWithChildren } from 'react';
7
-
import { useState } from 'react';
8
-
9
-
import Link from '@/components/Link';
10
-
import { useClientContext } from '@/hooks';
11
-
import { BASE_PATH } from '@/next.constants.mjs';
12
-
import { availableLocales } from '@/next.locales.mjs';
13
-
14
-
const Header: FC<PropsWithChildren> = ({ children }) => {
15
-
const [showLangPicker, setShowLangPicker] = useState(false);
16
-
const { resolvedTheme, setTheme } = useTheme();
17
-
18
-
const { pathname } = useClientContext();
19
-
const t = useTranslations();
20
-
21
-
const toggleLanguage = t('components.header.buttons.toggleLanguage');
22
-
const toggleTheme = t('components.header.buttons.toggleTheme');
23
-
24
-
return (
25
-
<header aria-label="Primary">
26
-
<div className="container">
27
-
<Link href="/" className="logo">
28
-
<Image
29
-
priority
30
-
width="111"
31
-
height="33"
32
-
src={`${BASE_PATH}/static/images/logo.svg`}
33
-
alt="Node.js"
34
-
/>
35
-
</Link>
36
-
37
-
{children}
38
-
39
-
<div className="switchers">
40
-
<button
41
-
className="theme-switcher"
42
-
type="button"
43
-
title={toggleTheme}
44
-
aria-label={toggleTheme}
45
-
onClick={() =>
46
-
setTheme(resolvedTheme === 'dark' ? 'light' : 'dark')
47
-
}
48
-
>
49
-
<Image
50
-
priority
51
-
width="28"
52
-
height="28"
53
-
className="dark-image"
54
-
src={`${BASE_PATH}/static/images/light-mode.svg`}
55
-
alt="Theme Switcher"
56
-
/>
57
-
58
-
<Image
59
-
priority
60
-
width="28"
61
-
height="28"
62
-
className="light-image"
63
-
src={`${BASE_PATH}/static/images/dark-mode.svg`}
64
-
alt="Theme Switcher"
65
-
/>
66
-
</button>
67
-
68
-
<button
69
-
className="lang-picker-toggler"
70
-
type="button"
71
-
title={toggleLanguage}
72
-
aria-label={toggleLanguage}
73
-
onClick={() => setShowLangPicker(!showLangPicker)}
74
-
aria-controls="lang-picker"
75
-
aria-expanded="false"
76
-
>
77
-
<Image
78
-
priority
79
-
width="25"
80
-
height="28"
81
-
src={`${BASE_PATH}/static/images/language-picker.svg`}
82
-
alt="Language Switcher"
83
-
/>
84
-
</button>
85
-
</div>
86
-
87
-
{showLangPicker && (
88
-
<ul className="lang-picker">
89
-
{availableLocales.map(locale => (
90
-
<li key={locale.code}>
91
-
<Link
92
-
title={locale.name}
93
-
locale={locale.code}
94
-
href={pathname}
95
-
onClick={() => setShowLangPicker(false)}
96
-
>
97
-
{locale.localName}
98
-
</Link>
99
-
</li>
100
-
))}
101
-
</ul>
102
-
)}
103
-
</div>
104
-
</header>
105
-
);
106
-
};
107
-
108
-
export default Header;
-69
components/Home/HomeDownloadButton.tsx
-69
components/Home/HomeDownloadButton.tsx
···
1
-
'use client';
2
-
3
-
import { useTranslations } from 'next-intl';
4
-
import type { FC } from 'react';
5
-
6
-
import Link from '@/components/Link';
7
-
import { useDetectOS } from '@/hooks';
8
-
import { DIST_URL } from '@/next.constants.mjs';
9
-
import type { NodeRelease } from '@/types';
10
-
import { getNodeDownloadUrl } from '@/util/getNodeDownloadUrl';
11
-
import { getNodejsChangelog } from '@/util/getNodeJsChangelog';
12
-
13
-
const HomeDownloadButton: FC<NodeRelease> = ({
14
-
major,
15
-
version,
16
-
versionWithPrefix,
17
-
isLts,
18
-
}) => {
19
-
const { os, bitness } = useDetectOS();
20
-
const t = useTranslations();
21
-
22
-
const nodeDownloadLink = getNodeDownloadUrl(versionWithPrefix, os, bitness);
23
-
const nodeApiLink = `${DIST_URL}latest-v${major}.x/docs/api/`;
24
-
const nodeAllDownloadsLink = `/download${isLts ? '/' : '/current'}`;
25
-
26
-
const downloadFile = t('components.home.homeDownloadButton.download', {
27
-
version,
28
-
isLts,
29
-
});
30
-
31
-
return (
32
-
<div className="home-downloadblock">
33
-
<a
34
-
href={nodeDownloadLink}
35
-
className="home-downloadbutton"
36
-
title={downloadFile}
37
-
data-version={versionWithPrefix}
38
-
>
39
-
{downloadFile}
40
-
41
-
<small>
42
-
{t('components.home.homeDownloadButton.tagline', { isLts })}
43
-
</small>
44
-
</a>
45
-
46
-
<ul className="list-divider-pipe home-secondary-links">
47
-
<li>
48
-
<Link href={nodeAllDownloadsLink}>
49
-
{t('components.home.homeDownloadButton.otherDownloads')}
50
-
</Link>
51
-
</li>
52
-
53
-
<li>
54
-
<a href={getNodejsChangelog(versionWithPrefix)}>
55
-
{t('components.home.homeDownloadButton.changelog')}
56
-
</a>
57
-
</li>
58
-
59
-
<li>
60
-
<a href={nodeApiLink}>
61
-
{t('components.home.homeDownloadButton.apiDocs')}
62
-
</a>
63
-
</li>
64
-
</ul>
65
-
</div>
66
-
);
67
-
};
68
-
69
-
export default HomeDownloadButton;
+78
components/Icons/Platform/Choco.tsx
+78
components/Icons/Platform/Choco.tsx
···
1
+
import type { FC, SVGProps } from 'react';
2
+
3
+
const Choco: FC<SVGProps<SVGSVGElement>> = props => (
4
+
<svg
5
+
width="32"
6
+
height="32"
7
+
viewBox="0 0 31.7 28.4"
8
+
enableBackground="new 0 0 31.7 28.4"
9
+
xmlns="http://www.w3.org/2000/svg"
10
+
{...props}
11
+
>
12
+
<g>
13
+
<polygon
14
+
fill="#924716"
15
+
points="27.6,27.2 5.7,27.2 5.7,1 27.6,1 27.6,6.9"
16
+
/>
17
+
<polygon fill="#793812" points="27.6,1 27.6,27.2 25.7,27.2 25.7,2.6" />
18
+
<polygon fill="#9F5326" points="25.4,2.6 3.5,2.6 3.5,1 27.3,1" />
19
+
<g>
20
+
<polygon
21
+
fill="#80B5E3"
22
+
points="27.6,27.2 3.7,27.2 3.7,1 8.5,1 12.6,4.2 16.6,2.6 19.1,5.7 23.8,4.9 25.7,10.7 27.6,18.1
23
+
30.5,21.1 29,23.6 31.7,28.4"
24
+
/>
25
+
<polygon
26
+
fill="#80B5E3"
27
+
points="3.7,27.2 3.7,1 0,0 1.9,4.2 0,7.5 1.9,10.8 0,14.1 1.9,17.3 0,20.6 1.9,23.9 0,28.4"
28
+
/>
29
+
</g>
30
+
<polygon
31
+
opacity="0.2"
32
+
fill="#FFFFFF"
33
+
points="10.4,2.6 5.4,2.6 3.5,1 8.3,1"
34
+
/>
35
+
<g>
36
+
<path
37
+
fill="#924716"
38
+
d="M18.3,13.7c-0.7,0.6-2.5,1.9-4.4,2.3c-2.3,0.5-3.6-1.4-3.1-3.2c0.5-2.1,2.8-3.7,4.8-3
39
+
c0.9,0.3,0.6,1.5,0.3,2.1c-0.8,1.5,0.3,1.7,0.8,1.2c1.5-1.6,2.4-4.3-0.2-5.3c-4-1.5-7.3,2.2-8.4,5.2c-1.7,4.8,2.4,9,7.1,5.8
40
+
c1.2-0.8,2.6-2.2,3.5-3.4C19.5,14.2,19,13.1,18.3,13.7z"
41
+
/>
42
+
<ellipse
43
+
transform="matrix(0.707 -0.7072 0.7072 0.707 -1.547 19.2306)"
44
+
fill="#924716"
45
+
cx="22.4"
46
+
cy="11.5"
47
+
rx="1.6"
48
+
ry="1.1"
49
+
/>
50
+
<ellipse
51
+
transform="matrix(0.707 -0.7072 0.7072 0.707 -4.7882 20.1076)"
52
+
fill="#924716"
53
+
cx="21.9"
54
+
cy="15.8"
55
+
rx="1.6"
56
+
ry="1.1"
57
+
/>
58
+
</g>
59
+
<polygon
60
+
opacity="0.2"
61
+
fill="#FFFFFF"
62
+
points="5.7,25.5 3.7,27.2 3.7,1 5.7,2.6"
63
+
/>
64
+
<g opacity="0.2">
65
+
<polygon
66
+
fill="#342565"
67
+
points="27.6,27.2 3.7,27.2 5.7,25.5 25.7,25.5"
68
+
/>
69
+
<polygon
70
+
fill="#342565"
71
+
points="27.6,27.2 25.7,25.5 25.7,10.7 27.6,18.1"
72
+
/>
73
+
</g>
74
+
</g>
75
+
</svg>
76
+
);
77
+
78
+
export default Choco;
+1
-1
components/MDX/SearchPage/index.tsx
+1
-1
components/MDX/SearchPage/index.tsx
···
71
71
: {};
72
72
73
73
const getDocumentURL = (siteSection: string, path: string) => {
74
-
const isAPIResult = siteSection.toLowerCase() === 'api';
74
+
const isAPIResult = siteSection.toLowerCase() === 'docs';
75
75
const basePath = isAPIResult ? BASE_URL : '';
76
76
return `${basePath}/${path}`;
77
77
};
-31
components/Pagination.tsx
-31
components/Pagination.tsx
···
1
-
import { useTranslations } from 'next-intl';
2
-
import type { FC } from 'react';
3
-
4
-
import Link from '@/components/Link';
5
-
import type { BlogPagination } from '@/types';
6
-
7
-
type PaginationProps = BlogPagination & { category: string };
8
-
9
-
const Pagination: FC<PaginationProps> = ({ category, next, prev }) => {
10
-
const t = useTranslations();
11
-
12
-
return (
13
-
<nav aria-label="pagination" className="pagination">
14
-
{prev && (
15
-
<Link href={`/blog/${category}/page/${prev}`}>
16
-
< {t('components.pagination.previous')}
17
-
</Link>
18
-
)}
19
-
20
-
{prev && next && ' | '}
21
-
22
-
{next && (
23
-
<Link href={`/blog/${category}/page/${next}`}>
24
-
{t('components.pagination.next')} >
25
-
</Link>
26
-
)}
27
-
</nav>
28
-
);
29
-
};
30
-
31
-
export default Pagination;
+2
components/__design__/platform-logos.stories.tsx
+2
components/__design__/platform-logos.stories.tsx
···
1
1
import type { Meta as MetaObj, StoryObj } from '@storybook/react';
2
2
3
3
import Apple from '@/components/Icons/Platform/Apple';
4
+
import Choco from '@/components/Icons/Platform/Choco';
4
5
import Docker from '@/components/Icons/Platform/Docker';
5
6
import Generic from '@/components/Icons/Platform/Generic';
6
7
import Homebrew from '@/components/Icons/Platform/Homebrew';
···
23
24
</div>
24
25
<div className="flex flex-col items-center gap-4">
25
26
<Generic width={64} height={64} />
27
+
<Choco width={64} height={64} />
26
28
</div>
27
29
</div>
28
30
),
+14
-45
components/withLayout.tsx
+14
-45
components/withLayout.tsx
···
1
1
import type { FC, PropsWithChildren } from 'react';
2
2
3
-
import LegacyAboutLayout from '@/layouts/AboutLayout';
4
-
import LegacyBlogCategoryLayout from '@/layouts/BlogCategoryLayout';
5
-
import LegacyBlogPostLayout from '@/layouts/BlogPostLayout';
6
-
import LegacyDefaultLayout from '@/layouts/DefaultLayout';
7
-
import LegacyDocsLayout from '@/layouts/DocsLayout';
8
-
import LegacyDownloadLayout from '@/layouts/DownloadLayout';
9
-
import LegacyIndexLayout from '@/layouts/IndexLayout';
10
-
import LegacyLearnLayout from '@/layouts/LearnLayout';
11
-
import AboutLayout from '@/layouts/New/About';
12
-
import BlogLayout from '@/layouts/New/Blog';
13
-
import DefaultLayout from '@/layouts/New/Default';
14
-
import DownloadLayout from '@/layouts/New/Download';
15
-
import HomeLayout from '@/layouts/New/Home';
16
-
import LearnLayout from '@/layouts/New/Learn';
17
-
import PostLayout from '@/layouts/New/Post';
18
-
import SearchLayout from '@/layouts/New/Search';
19
-
import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
20
-
import type { Layouts, LegacyLayouts } from '@/types';
3
+
import AboutLayout from '@/layouts/About';
4
+
import BlogLayout from '@/layouts/Blog';
5
+
import DefaultLayout from '@/layouts/Default';
6
+
import DownloadLayout from '@/layouts/Download';
7
+
import HomeLayout from '@/layouts/Home';
8
+
import LearnLayout from '@/layouts/Learn';
9
+
import PostLayout from '@/layouts/Post';
10
+
import SearchLayout from '@/layouts/Search';
11
+
import type { Layouts } from '@/types';
21
12
22
-
/** @deprecated these should be removed with the website redesin */
23
-
const legacyLayouts = {
24
-
'docs.hbs': LegacyDocsLayout,
25
-
'about.hbs': LegacyAboutLayout,
26
-
'blog-category.hbs': LegacyBlogCategoryLayout,
27
-
'blog-post.hbs': LegacyBlogPostLayout,
28
-
'download.hbs': LegacyDownloadLayout,
29
-
'index.hbs': LegacyIndexLayout,
30
-
'learn.hbs': LegacyLearnLayout,
31
-
'page.hbs': LegacyDefaultLayout,
32
-
} satisfies Record<LegacyLayouts, FC>;
33
-
34
-
/** all the currently available layouts from website redesign */
35
-
const redesignLayouts = {
13
+
const layouts = {
36
14
'about.hbs': AboutLayout,
37
15
'home.hbs': HomeLayout,
38
16
'learn.hbs': LearnLayout,
···
43
21
'download.hbs': DownloadLayout,
44
22
} satisfies Record<Layouts, FC>;
45
23
46
-
type WithLayout<L = Layouts | LegacyLayouts> = PropsWithChildren<{ layout: L }>;
24
+
type WithLayouProps<L = Layouts> = PropsWithChildren<{ layout: L }>;
47
25
48
-
const WithRedesign: FC<WithLayout<Layouts>> = ({ layout, children }) => {
49
-
const LayoutComponent = redesignLayouts[layout] ?? DefaultLayout;
50
-
51
-
return <LayoutComponent>{children}</LayoutComponent>;
52
-
};
53
-
54
-
/** @deprecated method to be removed once website redesign is finished */
55
-
const WithLegacy: FC<WithLayout<LegacyLayouts>> = ({ layout, children }) => {
56
-
const LayoutComponent = legacyLayouts[layout] ?? LegacyDefaultLayout;
26
+
const WithLayout: FC<WithLayouProps<Layouts>> = ({ layout, children }) => {
27
+
const LayoutComponent = layouts[layout] ?? DefaultLayout;
57
28
58
29
return <LayoutComponent>{children}</LayoutComponent>;
59
30
};
60
31
61
-
// Decides which Layout Connector to use based on the Environment
62
-
// @todo: This should be removed once we switch to Redesign
63
-
export default ENABLE_WEBSITE_REDESIGN ? WithRedesign : WithLegacy;
32
+
export default WithLayout;
+2
hooks/react-client/useBottomScrollListener.ts
+2
hooks/react-client/useBottomScrollListener.ts
+1
-1
hooks/react-client/useKeyboardCommands.ts
+1
-1
hooks/react-client/useKeyboardCommands.ts
+1
-1
i18n/locales/en.json
+1
-1
i18n/locales/en.json
···
286
286
"platform": "Platform"
287
287
},
288
288
"codeBox": {
289
-
"communityWarning": "Package Managers and their installation scripts are not maintained by the Node.js project.s"
289
+
"communityWarning": "Package managers and their installation scripts are not maintained by the Node.js project."
290
290
}
291
291
}
292
292
},
-12
layouts/AboutLayout.tsx
-12
layouts/AboutLayout.tsx
···
1
-
import type { FC, PropsWithChildren } from 'react';
2
-
3
-
import SideNavigation from '@/components/SideNavigation';
4
-
5
-
const AboutLayout: FC<PropsWithChildren> = ({ children }) => (
6
-
<div className="has-side-nav container">
7
-
<SideNavigation navigationKeys={['about', 'getInvolved']} />
8
-
<article dir="auto">{children}</article>
9
-
</div>
10
-
);
11
-
12
-
export default AboutLayout;
-17
layouts/BaseLayout.tsx
-17
layouts/BaseLayout.tsx
···
1
-
import type { FC, PropsWithChildren } from 'react';
2
-
3
-
import Footer from '@/components/Footer';
4
-
import Header from '@/components/Header';
5
-
import TopNavigation from '@/components/TopNavigation';
6
-
7
-
const BaseLayout: FC<PropsWithChildren> = ({ children }) => (
8
-
<>
9
-
<Header>
10
-
<TopNavigation />
11
-
</Header>
12
-
<main id="main">{children}</main>
13
-
<Footer />
14
-
</>
15
-
);
16
-
17
-
export default BaseLayout;
-56
layouts/BlogCategoryLayout.tsx
-56
layouts/BlogCategoryLayout.tsx
···
1
-
import { getTranslations } from 'next-intl/server';
2
-
import type { FC } from 'react';
3
-
4
-
import { getClientContext } from '@/client-context';
5
-
import FormattedTime from '@/components/Common/FormattedTime';
6
-
import Link from '@/components/Link';
7
-
import Pagination from '@/components/Pagination';
8
-
import getBlogData from '@/next-data/blogData';
9
-
10
-
const getCategoryData = async (pathname: string) => {
11
-
// pathname format can either be: /en/blog/{category}
12
-
// or /en/blog/{category}/page/{page}
13
-
// hence we attempt to interpolate the full /en/blog/{category}/page/{page}
14
-
// and in case of course no page argument is provided we define it to 1
15
-
// note that malformed routes can't happen as they are all statically generated
16
-
const [, , category = 'all', , page = 1] = pathname.split('/');
17
-
18
-
const { posts, pagination } = await getBlogData(category, Number(page));
19
-
20
-
return { posts, category, pagination };
21
-
};
22
-
23
-
// This is a React Async Server Component
24
-
// Note that Hooks cannot be used in a RSC async component
25
-
// Async Components do not get re-rendered at all.
26
-
const BlogCategoryLayout: FC = async () => {
27
-
const { pathname } = getClientContext();
28
-
29
-
const t = await getTranslations();
30
-
31
-
const { posts, pagination, category } = await getCategoryData(pathname);
32
-
33
-
return (
34
-
<div className="container" dir="auto">
35
-
<h2 style={{ textTransform: 'capitalize' }}>
36
-
{t('layouts.blogIndex.categoryName', {
37
-
category: category.replace('year-', ''),
38
-
})}
39
-
</h2>
40
-
41
-
<ul className="blog-index">
42
-
{posts.map(({ slug, date, title }) => (
43
-
<li key={slug}>
44
-
<FormattedTime date={date} />
45
-
46
-
<Link href={slug}>{title}</Link>
47
-
</li>
48
-
))}
49
-
</ul>
50
-
51
-
<Pagination category={category} {...pagination} />
52
-
</div>
53
-
);
54
-
};
55
-
56
-
export default BlogCategoryLayout;
-32
layouts/BlogPostLayout.tsx
-32
layouts/BlogPostLayout.tsx
···
1
-
import { useTranslations } from 'next-intl';
2
-
import type { FC, PropsWithChildren } from 'react';
3
-
4
-
import FormattedTime from '@/components/Common/FormattedTime';
5
-
import { useClientContext } from '@/hooks/server';
6
-
7
-
const BlogPostLayout: FC<PropsWithChildren> = ({ children }) => {
8
-
const t = useTranslations();
9
-
10
-
const {
11
-
frontmatter: { title, author, date },
12
-
} = useClientContext();
13
-
14
-
return (
15
-
<div className="container">
16
-
<article dir="auto">
17
-
<div className="blogpost-header">
18
-
<h1>{title}</h1>
19
-
<span className="blogpost-meta">
20
-
{t('layouts.blogPost.author.byLine', { author: author || null })}
21
-
22
-
<FormattedTime date={date} />
23
-
</span>
24
-
</div>
25
-
26
-
{children}
27
-
</article>
28
-
</div>
29
-
);
30
-
};
31
-
32
-
export default BlogPostLayout;
-7
layouts/DefaultLayout.tsx
-7
layouts/DefaultLayout.tsx
-9
layouts/DocsLayout.tsx
-9
layouts/DocsLayout.tsx
-51
layouts/DownloadLayout.tsx
-51
layouts/DownloadLayout.tsx
···
1
-
import type { FC, PropsWithChildren } from 'react';
2
-
3
-
import PrimaryDownloadMatrix from '@/components/Downloads/PrimaryDownloadMatrix';
4
-
import SecondaryDownloadMatrix from '@/components/Downloads/SecondaryDownloadMatrix';
5
-
import WithNodeRelease from '@/components/withNodeRelease';
6
-
import { useClientContext } from '@/hooks/server';
7
-
8
-
const DownloadLayout: FC<PropsWithChildren> = ({ children }) => {
9
-
const {
10
-
frontmatter: { downloads },
11
-
pathname,
12
-
} = useClientContext();
13
-
14
-
const isCurrentReleasePage = pathname.includes('/current');
15
-
16
-
return (
17
-
<div className="container">
18
-
<article dir="auto">
19
-
<div className="download-header">
20
-
<h1>{downloads.headline}</h1>
21
-
</div>
22
-
23
-
{children}
24
-
25
-
{isCurrentReleasePage && (
26
-
<WithNodeRelease status="Current">
27
-
{({ release }) => (
28
-
<>
29
-
<PrimaryDownloadMatrix {...release} />
30
-
<SecondaryDownloadMatrix {...release} />
31
-
</>
32
-
)}
33
-
</WithNodeRelease>
34
-
)}
35
-
36
-
{isCurrentReleasePage || (
37
-
<WithNodeRelease status={['Active LTS', 'Maintenance LTS']}>
38
-
{({ release }) => (
39
-
<>
40
-
<PrimaryDownloadMatrix {...release} />
41
-
<SecondaryDownloadMatrix {...release} />
42
-
</>
43
-
)}
44
-
</WithNodeRelease>
45
-
)}
46
-
</article>
47
-
</div>
48
-
);
49
-
};
50
-
51
-
export default DownloadLayout;
-9
layouts/IndexLayout.tsx
-9
layouts/IndexLayout.tsx
-12
layouts/LearnLayout.tsx
-12
layouts/LearnLayout.tsx
···
1
-
import type { FC, PropsWithChildren } from 'react';
2
-
3
-
import SideNavigation from '@/components/SideNavigation';
4
-
5
-
const LearnLayout: FC<PropsWithChildren> = ({ children }) => (
6
-
<div className="has-side-nav container">
7
-
<SideNavigation navigationKeys={['learn']} />
8
-
<article dir="auto">{children}</article>
9
-
</div>
10
-
);
11
-
12
-
export default LearnLayout;
+1
-1
layouts/New/About.tsx
layouts/About.tsx
+1
-1
layouts/New/About.tsx
layouts/About.tsx
···
4
4
import WithMetaBar from '@/components/withMetaBar';
5
5
import WithNavBar from '@/components/withNavBar';
6
6
import WithSidebar from '@/components/withSidebar';
7
-
import ArticleLayout from '@/layouts/New/Article';
7
+
import ArticleLayout from '@/layouts/Article';
8
8
9
9
const AboutLayout: FC<PropsWithChildren> = ({ children }) => (
10
10
<>
layouts/New/Article.tsx
layouts/Article.tsx
layouts/New/Article.tsx
layouts/Article.tsx
layouts/New/Base.tsx
layouts/Base.tsx
layouts/New/Base.tsx
layouts/Base.tsx
layouts/New/Blog.tsx
layouts/Blog.tsx
layouts/New/Blog.tsx
layouts/Blog.tsx
layouts/New/Centered.tsx
layouts/Centered.tsx
layouts/New/Centered.tsx
layouts/Centered.tsx
layouts/New/Content.tsx
layouts/Content.tsx
layouts/New/Content.tsx
layouts/Content.tsx
+1
-1
layouts/New/Default.tsx
layouts/Default.tsx
+1
-1
layouts/New/Default.tsx
layouts/Default.tsx
···
3
3
import WithFooter from '@/components/withFooter';
4
4
import WithNavBar from '@/components/withNavBar';
5
5
import WithSidebar from '@/components/withSidebar';
6
-
import ArticleLayout from '@/layouts/New/Article';
6
+
import ArticleLayout from '@/layouts/Article';
7
7
8
8
const DefaultLayout: FC<PropsWithChildren> = ({ children }) => (
9
9
<>
layouts/New/Download.tsx
layouts/Download.tsx
layouts/New/Download.tsx
layouts/Download.tsx
+1
-1
layouts/New/Home.tsx
layouts/Home.tsx
+1
-1
layouts/New/Home.tsx
layouts/Home.tsx
+1
-1
layouts/New/Learn.tsx
layouts/Learn.tsx
+1
-1
layouts/New/Learn.tsx
layouts/Learn.tsx
···
5
5
import WithNavBar from '@/components/withNavBar';
6
6
import WithProgressionSidebar from '@/components/withProgressionSidebar';
7
7
import WithSidebarCrossLinks from '@/components/withSidebarCrossLinks';
8
-
import ArticleLayout from '@/layouts/New/Article';
8
+
import ArticleLayout from '@/layouts/Article';
9
9
10
10
const LearnLayout: FC<PropsWithChildren> = ({ children }) => (
11
11
<>
+1
-1
layouts/New/Post.tsx
layouts/Post.tsx
+1
-1
layouts/New/Post.tsx
layouts/Post.tsx
···
7
7
import WithMetaBar from '@/components/withMetaBar';
8
8
import WithNavBar from '@/components/withNavBar';
9
9
import { useClientContext } from '@/hooks/react-server';
10
-
import ContentLayout from '@/layouts/New/Content';
10
+
import ContentLayout from '@/layouts/Content';
11
11
import {
12
12
mapAuthorToCardAuthors,
13
13
mapBlogCategoryToPreviewType,
layouts/New/Search.tsx
layouts/Search.tsx
layouts/New/Search.tsx
layouts/Search.tsx
layouts/New/layouts.module.css
layouts/layouts.module.css
layouts/New/layouts.module.css
layouts/layouts.module.css
+1
-29
next.config.mjs
+1
-29
next.config.mjs
···
1
1
'use strict';
2
2
3
-
import { resolve } from 'node:path';
4
-
5
3
import { withSentryConfig } from '@sentry/nextjs';
6
4
import withNextIntl from 'next-intl/plugin';
7
5
8
-
import {
9
-
BASE_PATH,
10
-
ENABLE_STATIC_EXPORT,
11
-
ENABLE_WEBSITE_REDESIGN,
12
-
} from './next.constants.mjs';
6
+
import { BASE_PATH, ENABLE_STATIC_EXPORT } from './next.constants.mjs';
13
7
import { redirects, rewrites } from './next.rewrites.mjs';
14
8
import {
15
9
SENTRY_DSN,
···
65
59
// Tree-shakes modules from Sentry Bundle
66
60
config.plugins.push(new webpack.DefinePlugin(SENTRY_EXTENSIONS));
67
61
68
-
// This allows us to customise our global styles on build-tim,e
69
-
// based on if we're running the Website Redesign or not
70
-
config.resolve.alias = {
71
-
...config.resolve.alias,
72
-
// @deprecated remove when website redesign is done
73
-
globalStyles$: resolve(
74
-
ENABLE_WEBSITE_REDESIGN
75
-
? './styles/new/index.css'
76
-
: './styles/old/index.css'
77
-
),
78
-
};
79
-
80
62
return config;
81
63
},
82
64
experimental: {
83
-
turbo: {
84
-
resolveAlias: {
85
-
// This allows us to customise our global styles on build-tim,e
86
-
// based on if we're running the Website Redesign or not
87
-
// @deprecated remove when website redesign is done
88
-
globalStyles: ENABLE_WEBSITE_REDESIGN
89
-
? './styles/new/index.css'
90
-
: './styles/old/index.css',
91
-
},
92
-
},
93
65
// Some of our static pages from `getStaticProps` have a lot of data
94
66
// since we pass the fully-compiled MDX page from `MDXRemote` through
95
67
// a page's static props.
+1
-12
next.constants.mjs
+1
-12
next.constants.mjs
···
37
37
process.env.NEXT_PUBLIC_STATIC_EXPORT === true;
38
38
39
39
/**
40
-
* This is used for enabling the New Website Redesign Layouts
41
-
*
42
-
* Note that this is a manual Environment Variable defined by us if necessary.
43
-
*/
44
-
export const ENABLE_WEBSITE_REDESIGN =
45
-
process.env.NEXT_PUBLIC_ENABLE_REDESIGN === 'true' ||
46
-
process.env.NEXT_PUBLIC_ENABLE_REDESIGN === true;
47
-
48
-
/**
49
40
* This is used for any place that requires the full canonical URL path for the Node.js Website (and its deployment), such as for example, the Node.js RSS Feed.
50
41
*
51
42
* This variable can either come from the Vercel Deployment as `NEXT_PUBLIC_VERCEL_URL` or from the `NEXT_PUBLIC_BASE_URL` Environment Variable that is manually defined
···
110
101
111
102
/**
112
103
* This defines how many blog posts each pagination page should have
113
-
*
114
-
* @todo: update the value when moving to website redesign
115
104
*/
116
-
export const BLOG_POSTS_PER_PAGE = ENABLE_WEBSITE_REDESIGN ? 6 : 20;
105
+
export const BLOG_POSTS_PER_PAGE = 6;
117
106
118
107
/**
119
108
* The `localStorage` key to store the theme choice of `next-themes`
-3
next.dynamic.constants.mjs
-3
next.dynamic.constants.mjs
···
18
18
// This is used to ignore all blog routes except for the English language
19
19
({ locale, pathname }) =>
20
20
locale !== defaultLocale.code && /^blog/.test(pathname),
21
-
// Do not statically build the redesign pages on the static export
22
-
// @deprecated this should be removed once we remove the legacy website
23
-
({ pathname }) => /^new-design/.test(pathname),
24
21
];
25
22
26
23
/**
+1
-10
next.fonts.ts
+1
-10
next.fonts.ts
···
1
-
import { Source_Sans_3, Open_Sans, IBM_Plex_Mono } from 'next/font/google';
2
-
3
-
// This configures the Next.js Font for Source Sans
4
-
// We then export a variable and class name to be used
5
-
// within Tailwind (tailwind.config.ts) and Storybook (preview.js)
6
-
export const SOURCE_SANS = Source_Sans_3({
7
-
weight: ['400', '600'],
8
-
display: 'fallback',
9
-
subsets: ['latin'],
10
-
});
1
+
import { Open_Sans, IBM_Plex_Mono } from 'next/font/google';
11
2
12
3
// This configures the Next.js Font for Open Sans
13
4
// We then export a variable and class name to be used
+2
-10
next.mdx.use.mjs
+2
-10
next.mdx.use.mjs
···
18
18
import SourceButton from './components/Downloads/Release/SourceButton';
19
19
import VerifyingBinariesLink from './components/Downloads/Release/VerifyingBinariesLink';
20
20
import VersionDropdown from './components/Downloads/Release/VersionDropdown';
21
-
import HomeDownloadButton from './components/Home/HomeDownloadButton';
22
21
import Link from './components/Link';
23
22
import UpcomingMeetings from './components/MDX/Calendar/UpcomingMeetings';
24
23
import MDXCodeBox from './components/MDX/CodeBox';
···
27
26
import WithBadge from './components/withBadge';
28
27
import WithBanner from './components/withBanner';
29
28
import WithNodeRelease from './components/withNodeRelease';
30
-
import { ENABLE_WEBSITE_REDESIGN } from './next.constants.mjs';
31
29
32
30
/**
33
31
* A full list of React Components that we want to pass through to MDX
···
35
33
* @satisfies {import('mdx/types').MDXComponents}
36
34
*/
37
35
export const mdxComponents = {
38
-
// Legacy Component
39
-
HomeDownloadButton: HomeDownloadButton,
40
-
// Legacy Component
41
36
DownloadReleasesTable: DownloadReleasesTable,
42
37
// HOC for getting Node.js Release Metadata
43
38
WithNodeRelease: WithNodeRelease,
···
97
92
export const htmlComponents = {
98
93
// Renders a Link Component for `a` tags
99
94
a: Link,
100
-
// @deprecated once the website redesign happens
101
-
// switch to only use the Blockquote Component
102
-
blockquote: ENABLE_WEBSITE_REDESIGN
103
-
? Blockquote
104
-
: ({ children }) => <div className="highlight-box">{children}</div>,
95
+
// Renders a Blockquote Component for `blockquote` tags
96
+
blockquote: Blockquote,
105
97
// Renders a CodeBox Component for `pre` tags
106
98
pre: MDXCodeBox,
107
99
};
-24
next.rewrites.mjs
-24
next.rewrites.mjs
···
1
1
'use strict';
2
2
3
-
import { ENABLE_WEBSITE_REDESIGN } from './next.constants.mjs';
4
3
import { siteRedirects } from './next.json.mjs';
5
4
import { availableLocaleCodes } from './next.locales.mjs';
6
5
···
44
43
destination,
45
44
})
46
45
);
47
-
48
-
// This allows us to remap legacy website URLs to the temporary redesign ones
49
-
// @todo: remove this once website redesign is done
50
-
if (ENABLE_WEBSITE_REDESIGN) {
51
-
mappedRewrites.push(
52
-
{
53
-
source: localesMatch,
54
-
destination: '/:locale/new-design',
55
-
},
56
-
{
57
-
source: '/:locale/download',
58
-
destination: '/:locale/new-design/download',
59
-
},
60
-
{
61
-
source: '/:locale/download/:path',
62
-
destination: '/:locale/new-design/download/:path',
63
-
},
64
-
{
65
-
source: '/:locale/download/:path/:version',
66
-
destination: '/:locale/new-design/download/:path/:version',
67
-
}
68
-
);
69
-
}
70
46
71
47
return { afterFiles: mappedRewrites };
72
48
};
-1
package.json
-1
package.json
···
17
17
"scripts": {
18
18
"scripts:release-post": "cross-env NODE_NO_WARNINGS=1 node scripts/release-post/index.mjs",
19
19
"serve": "cross-env NODE_NO_WARNINGS=1 next dev --turbo",
20
-
"serve:redesign": "cross-env NEXT_PUBLIC_ENABLE_REDESIGN=true npm run serve",
21
20
"build": "cross-env NODE_NO_WARNINGS=1 next build",
22
21
"start": "cross-env NODE_NO_WARNINGS=1 next start",
23
22
"deploy": "cross-env NEXT_PUBLIC_STATIC_EXPORT=true npm run build",
+5
-1
pages/en/about/index.mdx
+5
-1
pages/en/about/index.mdx
-34
pages/en/download/current.md
-34
pages/en/download/current.md
···
1
-
---
2
-
layout: download.hbs
3
-
title: Download
4
-
download: Download
5
-
downloads:
6
-
headline: Downloads
7
-
lts: LTS
8
-
current: Current
9
-
tagline-current: Latest Features
10
-
tagline-lts: Recommended For Most Users
11
-
display-hint: Display downloads for
12
-
intro: >
13
-
Download the Node.js source code or a pre-built installer for your platform, and start developing today.
14
-
currentVersion: Latest Current Version
15
-
buildInstructions: Building Node.js from source on supported platforms
16
-
WindowsInstaller: Windows Installer
17
-
WindowsBinary: Windows Binary
18
-
MacOSInstaller: macOS Installer
19
-
MacOSBinary: macOS Binary
20
-
LinuxBinaries: Linux Binaries
21
-
SourceCode: Source Code
22
-
additional:
23
-
headline: Additional Platforms
24
-
intro: >
25
-
Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release.
26
-
platform: Platform
27
-
provider: Provider
28
-
SmartOSBinaries: SmartOS Binaries
29
-
DockerImage: Docker Image
30
-
officialDockerImage: Official Node.js Docker Image
31
-
LinuxPowerSystems: Linux on Power LE Systems
32
-
LinuxSystemZ: Linux on System z
33
-
AIXPowerSystems: AIX on Power Systems
34
-
---
-34
pages/en/download/index.md
-34
pages/en/download/index.md
···
1
-
---
2
-
layout: download.hbs
3
-
title: Download
4
-
download: Download
5
-
downloads:
6
-
headline: Downloads
7
-
lts: LTS
8
-
current: Current
9
-
tagline-current: Latest Features
10
-
tagline-lts: Recommended For Most Users
11
-
display-hint: Display downloads for
12
-
intro: >
13
-
Download the Node.js source code or a pre-built installer for your platform, and start developing today.
14
-
currentVersion: Latest LTS Version
15
-
buildInstructions: Building Node.js from source on supported platforms
16
-
WindowsInstaller: Windows Installer
17
-
WindowsBinary: Windows Binary
18
-
MacOSInstaller: macOS Installer
19
-
MacOSBinary: macOS Binary
20
-
LinuxBinaries: Linux Binaries
21
-
SourceCode: Source Code
22
-
additional:
23
-
headline: Additional Platforms
24
-
intro: >
25
-
Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release.
26
-
platform: Platform
27
-
provider: Provider
28
-
SmartOSBinaries: SmartOS Binaries
29
-
DockerImage: Docker Image
30
-
officialDockerImage: Official Node.js Docker Image
31
-
LinuxPowerSystems: Linux on Power LE Systems
32
-
LinuxSystemZ: Linux on System z
33
-
AIXPowerSystems: AIX on Power Systems
34
-
---
-410
pages/en/download/package-manager.md
-410
pages/en/download/package-manager.md
···
1
-
---
2
-
layout: docs.hbs
3
-
title: Installing Node.js via package manager
4
-
---
5
-
6
-
# Installing Node.js via package manager
7
-
8
-
**_Note:_** The packages on this page are maintained and supported by their respective packagers, **not** the Node.js core team. Please report any issues you encounter to the package maintainer. If it turns out your issue is a bug in Node.js itself, the maintainer will report the issue upstream.
9
-
10
-
---
11
-
12
-
- [Alpine Linux](#alpine-linux)
13
-
- [Android](#android)
14
-
- [Arch Linux](#arch-linux)
15
-
- [CentOS, Fedora and Red Hat Enterprise Linux](#centos-fedora-and-red-hat-enterprise-linux)
16
-
- [Debian and Ubuntu based Linux distributions](#debian-and-ubuntu-based-linux-distributions)
17
-
- [fnm](#fnm)
18
-
- [FreeBSD](#freebsd)
19
-
- [Gentoo](#gentoo)
20
-
- [IBM i](#ibm-i)
21
-
- [macOS](#macos)
22
-
- [n](#n)
23
-
- [NetBSD](#netbsd)
24
-
- [Nodenv](#nodenv)
25
-
- [nvm](#nvm)
26
-
- [nvs](#nvs)
27
-
- [OpenBSD](#openbsd)
28
-
- [openSUSE and SLE](#opensuse-and-sle)
29
-
- [SmartOS and illumos](#smartos-and-illumos)
30
-
- [Snap](#snap)
31
-
- [Solus](#solus)
32
-
- [Void Linux](#void-linux)
33
-
- [Windows](#windows-1)
34
-
- [z/OS](#zos)
35
-
36
-
---
37
-
38
-
## Alpine Linux
39
-
40
-
Node.js LTS and npm packages are available in the Main Repository.
41
-
42
-
```bash
43
-
apk add nodejs npm
44
-
```
45
-
46
-
Node.js Current can be installed from the Community Repository.
47
-
48
-
```bash
49
-
apk add nodejs-current
50
-
```
51
-
52
-
## Android
53
-
54
-
Android support is still experimental in Node.js, so precompiled binaries are not yet provided by Node.js developers.
55
-
56
-
However, there are some third-party solutions. For example, [Termux](https://termux.com/) community provides terminal emulator and Linux environment for Android, as well as own package manager and [extensive collection](https://github.com/termux/termux-packages) of many precompiled applications. This command in Termux app will install the last available Node.js version:
57
-
58
-
```bash
59
-
pkg install nodejs
60
-
```
61
-
62
-
Currently, Termux Node.js binaries are linked against `system-icu` (depending on `libicu` package).
63
-
64
-
## Arch Linux
65
-
66
-
Node.js and npm packages are available in the Community Repository.
67
-
68
-
```bash
69
-
pacman -S nodejs npm
70
-
```
71
-
72
-
## CentOS, Fedora and Red Hat Enterprise Linux
73
-
74
-
Node.js is available as a module called `nodejs` in CentOS/RHEL 8 and Fedora.
75
-
76
-
```bash
77
-
dnf module install nodejs:<stream>
78
-
```
79
-
80
-
where `<stream>` corresponds to the major version of Node.js.
81
-
To see a list of available streams:
82
-
83
-
```bash
84
-
dnf module list nodejs
85
-
```
86
-
87
-
For example, to install Node.js 18:
88
-
89
-
```bash
90
-
dnf module install nodejs:18/common
91
-
```
92
-
93
-
### Alternatives
94
-
95
-
These resources provide packages compatible with CentOS, Fedora, and RHEL.
96
-
97
-
- [Node.js snaps](#snap) maintained and supported at https://github.com/nodejs/snap
98
-
- [Node.js binary distributions](#debian-and-ubuntu-based-linux-distributions) maintained and supported by [NodeSource](https://github.com/nodesource/distributions)
99
-
100
-
## Debian and Ubuntu based Linux distributions
101
-
102
-
[Node.js binary distributions](https://github.com/nodesource/distributions) are available from NodeSource.
103
-
104
-
### Alternatives
105
-
106
-
Packages compatible with Debian and Ubuntu based Linux distributions are available via [Node.js snaps](#snap).
107
-
108
-
## fnm
109
-
110
-
Fast and simple Node.js version manager built in Rust used to manage multiple released Node.js versions. It allows you to perform operations like install, uninstall, switch Node versions automatically based on the current directory, etc.
111
-
To install fnm, use this [install script](https://github.com/Schniz/fnm#using-a-script-macoslinux).
112
-
113
-
fnm has cross-platform support (macOS, Windows, Linux) & all popular shells (Bash, Zsh, Fish, PowerShell, Windows Command Line Prompt).
114
-
fnm is built with speed in mind and compatibility support for `.node-version` and `.nvmrc` files.
115
-
116
-
## FreeBSD
117
-
118
-
The most recent release of Node.js is available via the [www/node](https://www.freshports.org/www/node) port.
119
-
120
-
Install a binary package via [pkg](https://www.freebsd.org/cgi/man.cgi?pkg):
121
-
122
-
```bash
123
-
pkg install node
124
-
```
125
-
126
-
Or compile it on your own using [ports](https://www.freebsd.org/cgi/man.cgi?ports):
127
-
128
-
```bash
129
-
cd /usr/ports/www/node && make install
130
-
```
131
-
132
-
## Gentoo
133
-
134
-
Node.js is available in the portage tree.
135
-
136
-
```bash
137
-
emerge nodejs
138
-
```
139
-
140
-
## IBM i
141
-
142
-
LTS versions of Node.js are available from IBM, and are available via [the 'yum' package manager](https://ibm.biz/ibmi-rpms). The package name is `nodejs` followed by the major version number (for instance, `nodejs18`, `nodejs20` etc)
143
-
144
-
To install Node.js 20.x from the command line, run the following as a user with \*ALLOBJ special authority:
145
-
146
-
```bash
147
-
yum install nodejs20
148
-
```
149
-
150
-
Node.js can also be installed with the IBM i Access Client Solutions product. See [this support document](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) for more details
151
-
152
-
## macOS
153
-
154
-
Download the [macOS Installer](/#home-downloadhead) directly from the [nodejs.org](https://nodejs.org/) web site.
155
-
156
-
_If you want to download the package with bash:_
157
-
158
-
```bash
159
-
curl "https://nodejs.org/dist/latest/$(curl -s https://nodejs.org/dist/latest/ | grep "pkg" | cut -d'"' -f 2)" -o "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/"
160
-
```
161
-
162
-
### Alternatives
163
-
164
-
Using **[Homebrew](https://brew.sh/)**:
165
-
166
-
```bash
167
-
brew install node
168
-
```
169
-
170
-
Using **[MacPorts](https://www.macports.org/)**:
171
-
172
-
```bash
173
-
port install nodejs<major version>
174
-
175
-
# Example
176
-
port install nodejs7
177
-
```
178
-
179
-
Using **[pkgsrc](https://pkgsrc.joyent.com/install-on-macos/)**:
180
-
181
-
Install the binary package:
182
-
183
-
```bash
184
-
pkgin -y install nodejs
185
-
```
186
-
187
-
Or build manually from pkgsrc:
188
-
189
-
```bash
190
-
cd pkgsrc/lang/nodejs && bmake install
191
-
```
192
-
193
-
## n
194
-
195
-
`n` is a simple to use Node.js version manager for Mac and Linux. Specify the target version to install using a rich syntax,
196
-
or select from a menu of previously downloaded versions. The versions are installed system-wide or user-wide, and for more
197
-
targeted use you can run a version directly from the cached downloads.
198
-
199
-
See the [homepage](https://github.com/tj/n) for install methods (bootstrap, npm, Homebrew, third-party), and all the usage details.
200
-
201
-
If you already have `npm` then installing `n` and then the newest LTS `node` version is as simple as:
202
-
203
-
```
204
-
npm install -g n
205
-
n lts
206
-
```
207
-
208
-
## NetBSD
209
-
210
-
Node.js is available in the pkgsrc tree:
211
-
212
-
```bash
213
-
cd /usr/pkgsrc/lang/nodejs && make install
214
-
```
215
-
216
-
Or install a binary package (if available for your platform) using pkgin:
217
-
218
-
```bash
219
-
pkgin -y install nodejs
220
-
```
221
-
222
-
## Nodenv
223
-
224
-
`nodenv` is a lightweight node version manager, similar to `nvm`. It's simple and predictable. A rich plugin ecosystem lets you tailor it to suit your needs. Use `nodenv` to pick a Node version for your application and guarantee that your development environment matches production.
225
-
226
-
Nodenv installation instructions are maintained [on its Github page](https://github.com/nodenv/nodenv#installation). Please visit that page to ensure you're following the latest version of the installation steps.
227
-
228
-
## nvm
229
-
230
-
Node Version Manager is a bash script used to manage multiple released Node.js versions. It allows
231
-
you to perform operations like install, uninstall, switch version, etc.
232
-
To install nvm, use this [install script](https://github.com/nvm-sh/nvm#install--update-script).
233
-
234
-
On Unix / OS X systems Node.js built from source can be installed using
235
-
[nvm](https://github.com/creationix/nvm) by installing into the location that nvm expects:
236
-
237
-
```bash
238
-
env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX=""
239
-
```
240
-
241
-
After this you can use `nvm` to switch between released versions and versions
242
-
built from source.
243
-
For example, if the version of Node.js is v8.0.0-pre:
244
-
245
-
```bash
246
-
nvm use 8
247
-
```
248
-
249
-
Once the official release is out you will want to uninstall the version built
250
-
from source:
251
-
252
-
```bash
253
-
nvm uninstall 8
254
-
```
255
-
256
-
## nvs
257
-
258
-
#### Windows
259
-
260
-
The `nvs` version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems
261
-
262
-
To install `nvs` on Windows go to the [release page](https://github.com/jasongin/nvs/releases) here and download the MSI installer file of the latest release.
263
-
264
-
You can also use `chocolatey` to install it:
265
-
266
-
```bash
267
-
choco install nvs
268
-
```
269
-
270
-
#### macOS,UnixLike
271
-
272
-
You can find the documentation regarding the installation steps of `nvs` in macOS/Unix-like systems [here](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux)
273
-
274
-
#### Usage
275
-
276
-
After this you can use `nvs` to switch between different versions of node.
277
-
278
-
To add the latest version of node:
279
-
280
-
```bash
281
-
nvs add latest
282
-
```
283
-
284
-
Or to add the latest LTS version of node:
285
-
286
-
```bash
287
-
nvs add lts
288
-
```
289
-
290
-
Then run the `nvs use` command to add a version of node to your `PATH` for the current shell:
291
-
292
-
```bash
293
-
$ nvs use lts
294
-
PATH -= %LOCALAPPDATA%\nvs\default
295
-
PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64
296
-
```
297
-
298
-
To add it to `PATH` permanently, use `nvs link`:
299
-
300
-
```bash
301
-
nvs link lts
302
-
```
303
-
304
-
## OpenBSD
305
-
306
-
Node.js is available through the ports system.
307
-
308
-
```bash
309
-
/usr/ports/lang/node
310
-
```
311
-
312
-
Using [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) on OpenBSD:
313
-
314
-
```bash
315
-
pkg_add node
316
-
```
317
-
318
-
## openSUSE and SLE
319
-
320
-
Node.js is available in the main repositories under the following packages:
321
-
322
-
- **openSUSE Leap 15.2**: `nodejs10`, `nodejs12`, `nodejs14`
323
-
- **openSUSE Tumbleweed**: `nodejs20`
324
-
- **SUSE Linux Enterprise Server (SLES) 12**: `nodejs10`, `nodejs12`, and `nodejs14`
325
-
(The "Web and Scripting Module" must be [enabled](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12-SP5/#intro-modulesExtensionsRelated).)
326
-
- **SUSE Linux Enterprise Server (SLES) 15 SP2**: `nodejs10`, `nodejs12`, and `nodejs14`
327
-
(The "Web and Scripting Module" must be [enabled](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/15/#Intro.Module).)
328
-
329
-
For example, to install Node.js 14.x on openSUSE Leap 15.2, run the following as root:
330
-
331
-
```bash
332
-
zypper install nodejs14
333
-
```
334
-
335
-
Different major versions of Node can be installed and used concurrently.
336
-
337
-
## SmartOS and illumos
338
-
339
-
SmartOS images come with pkgsrc pre-installed. On other illumos distributions, first install **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, then you may install the binary package as normal:
340
-
341
-
```bash
342
-
pkgin -y install nodejs
343
-
```
344
-
345
-
Or build manually from pkgsrc:
346
-
347
-
```bash
348
-
cd pkgsrc/lang/nodejs && bmake install
349
-
```
350
-
351
-
## Snap
352
-
353
-
[Node.js snaps](https://github.com/nodejs/snap) are available as [`node`](https://snapcraft.io/node) on the Snap store.
354
-
355
-
## Solus
356
-
357
-
Solus provides Node.js in its main repository.
358
-
359
-
```bash
360
-
sudo eopkg install nodejs
361
-
```
362
-
363
-
## Void Linux
364
-
365
-
Void Linux ships Node.js stable in the main repository.
366
-
367
-
```bash
368
-
xbps-install -Sy nodejs
369
-
```
370
-
371
-
## Windows
372
-
373
-
Download the [Windows Installer](/#home-downloadhead) directly from the [nodejs.org](https://nodejs.org/) web site.
374
-
375
-
### Alternatives
376
-
377
-
Using **[Winget](https://aka.ms/winget-cli)**:
378
-
379
-
```bash
380
-
winget install OpenJS.NodeJS
381
-
# or for LTS
382
-
winget install OpenJS.NodeJS.LTS
383
-
```
384
-
385
-
After running one of the two commands above, it may be necessary to restart the
386
-
terminal emulator before the `node` CLI command becomes available.
387
-
388
-
Using **[Chocolatey](https://chocolatey.org/)**:
389
-
390
-
```bash
391
-
cinst nodejs
392
-
# or for full install with npm
393
-
cinst nodejs.install
394
-
```
395
-
396
-
Using **[Scoop](https://scoop.sh/)**:
397
-
398
-
```bash
399
-
scoop install nodejs
400
-
# or for LTS
401
-
scoop install nodejs-lts
402
-
```
403
-
404
-
## z/OS
405
-
406
-
IBM® SDK for Node.js - z/OS® is available in two installation formats,
407
-
SMP/E and PAX. Select the installation format that applies to you:
408
-
409
-
- [Installing and configuring SMP/E edition of Node.js on z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-smpe-edition)
410
-
- [Installing and configuring PAX edition of Node.js on z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-pax-edition)
+109
-11
pages/en/index.mdx
+109
-11
pages/en/index.mdx
···
1
1
---
2
-
layout: index.hbs
2
+
title: Run JavaScript Everywhere
3
+
layout: home.hbs
3
4
---
4
5
5
-
Node.js® is an open-source, cross-platform JavaScript runtime environment.
6
+
<section>
7
+
<WithBadge section="index" />
6
8
7
-
<WithBanner section="index" />
9
+
<div>
10
+
<h1 className="special">Run JavaScript Everywhere</h1>
8
11
9
-
<h2>Download Node.js®</h2>
12
+
Node.js® is a free, open-source, cross-platform JavaScript runtime
13
+
environment that lets developers create servers, web apps,
14
+
command line tools and scripts.
10
15
11
-
<WithNodeRelease status={['Active LTS', 'Maintenance LTS']}>
12
-
{({ release }) => <HomeDownloadButton {...release} />}
13
-
</WithNodeRelease>
16
+
</div>
14
17
15
-
<WithNodeRelease status="Current">
16
-
{({ release }) => <HomeDownloadButton {...release} />}
17
-
</WithNodeRelease>
18
+
<div>
19
+
<WithNodeRelease status={['Active LTS', 'Maintenance LTS']}>
20
+
{({ release }) => (
21
+
<>
22
+
<DownloadButton release={release}>Download Node.js (LTS)</DownloadButton>
23
+
<small>
24
+
Downloads Node.js <b>{release.versionWithPrefix}</b>
25
+
<sup title="Downloads a Node.js installer for your current platform">1</sup> with long-term support.
26
+
Node.js can also be installed via <a href="/download/package-manager">package managers</a>.
27
+
</small>
28
+
</>
29
+
)}
30
+
</WithNodeRelease>
31
+
<WithNodeRelease status="Current">
32
+
{({ release }) => (
33
+
<small>
34
+
Want new features sooner?
35
+
Get <b>Node.js <DownloadLink release={release}>{release.versionWithPrefix}</DownloadLink></b>
36
+
<sup title="Downloads a Node.js installer for your current platform">1</sup> instead.
37
+
</small>
38
+
)}
39
+
</WithNodeRelease>
40
+
</div>
41
+
</section>
18
42
19
-
For information about supported releases, see the [release schedule](/about/previous-releases).
43
+
<section>
44
+
<div>
45
+
```js displayName="Create an HTTP Server"
46
+
import { createServer } from 'node:http';
47
+
48
+
const server = createServer((req, res) => {
49
+
res.writeHead(200, { 'Content-Type': 'text/plain' });
50
+
res.end('Hello World!\n');
51
+
});
52
+
53
+
// starts a simple http server locally on port 3000
54
+
server.listen(3000, '127.0.0.1', () => {
55
+
console.log('Listening on 127.0.0.1:3000');
56
+
});
57
+
```
58
+
59
+
```js displayName="Write Tests"
60
+
import assert from 'node:assert';
61
+
import test from 'node:test';
62
+
63
+
test('that 1 is equal 1', () => {
64
+
assert.strictEqual(1, 1);
65
+
});
66
+
67
+
test('that throws as 1 is not equal 2', () => {
68
+
// throws an exception because 1 != 2
69
+
assert.strictEqual(1, 2);
70
+
});
71
+
```
72
+
73
+
```js displayName="Read and Hash a File"
74
+
import { createHash } from 'node:crypto';
75
+
import { readFile } from 'node:fs/promises';
76
+
77
+
const hasher = createHash('sha1');
78
+
const fileContent = await readFile('./package.json');
79
+
80
+
hasher.setEncoding('hex');
81
+
hasher.write(fileContent);
82
+
hasher.end();
83
+
84
+
const fileHash = hasher.read();
85
+
```
86
+
87
+
```js displayName="Read Streams"
88
+
import { createReadStream, createWriteStream } from 'node:fs';
89
+
90
+
const res = await fetch('https://nodejs.org/dist/index.json');
91
+
const json = await res.json(); // yields a json object
92
+
93
+
const readableStream = createReadStream('./package.json');
94
+
const writableStream = createWriteStream('./package2.json');
95
+
96
+
readableStream.setEncoding('utf8');
97
+
98
+
readableStream.on('data', chunk => writableStream.write(chunk));
99
+
```
100
+
101
+
```js displayName="Work with Threads"
102
+
import { Worker, isMainThread,
103
+
workerData, parentPort } from 'node:worker_threads';
104
+
105
+
if (isMainThread) {
106
+
const data = 'some data';
107
+
const worker = new Worker(import.meta.filename, { workerData: data });
108
+
worker.on('message', msg => console.log('Reply from Thread:', msg));
109
+
} else {
110
+
const source = workerData;
111
+
parentPort.postMessage(btoa(source.toUpperCase()));
112
+
}
113
+
```
114
+
115
+
</div>
116
+
Learn more what Node.js is able to offer with our [Learning materials](/learn).
117
+
</section>
pages/en/new-design/download/current.mdx
pages/en/download/current.mdx
pages/en/new-design/download/current.mdx
pages/en/download/current.mdx
pages/en/new-design/download/index.mdx
pages/en/download/index.mdx
pages/en/new-design/download/index.mdx
pages/en/download/index.mdx
+3
-3
pages/en/new-design/download/package-manager/all.md
pages/en/download/package-manager/all.md
+3
-3
pages/en/new-design/download/package-manager/all.md
pages/en/download/package-manager/all.md
···
139
139
140
140
## IBM i
141
141
142
-
LTS versions of Node.js are available from IBM, and are available via [the 'yum' package manager](https://ibm.biz/ibmi-rpms). The package name is `nodejs` followed by the major version number (for instance, `nodejs12`, `nodejs14` etc)
142
+
LTS versions of Node.js are available from IBM, and are available via [the 'yum' package manager](https://ibm.biz/ibmi-rpms). The package name is `nodejs` followed by the major version number (for instance, `nodejs18`, `nodejs20` etc)
143
143
144
-
To install Node.js 14.x from the command line, run the following as a user with \*ALLOBJ special authority:
144
+
To install Node.js 20.x from the command line, run the following as a user with \*ALLOBJ special authority:
145
145
146
146
```bash
147
-
yum install nodejs14
147
+
yum install nodejs20
148
148
```
149
149
150
150
Node.js can also be installed with the IBM i Access Client Solutions product. See [this support document](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) for more details
pages/en/new-design/download/package-manager/current.mdx
pages/en/download/package-manager/current.mdx
pages/en/new-design/download/package-manager/current.mdx
pages/en/download/package-manager/current.mdx
pages/en/new-design/download/package-manager/index.mdx
pages/en/download/package-manager/index.mdx
pages/en/new-design/download/package-manager/index.mdx
pages/en/download/package-manager/index.mdx
pages/en/new-design/download/prebuilt-binaries/current.mdx
pages/en/download/prebuilt-binaries/current.mdx
pages/en/new-design/download/prebuilt-binaries/current.mdx
pages/en/download/prebuilt-binaries/current.mdx
pages/en/new-design/download/prebuilt-binaries/index.mdx
pages/en/download/prebuilt-binaries/index.mdx
pages/en/new-design/download/prebuilt-binaries/index.mdx
pages/en/download/prebuilt-binaries/index.mdx
pages/en/new-design/download/source-code/current.mdx
pages/en/download/source-code/current.mdx
pages/en/new-design/download/source-code/current.mdx
pages/en/download/source-code/current.mdx
pages/en/new-design/download/source-code/index.mdx
pages/en/download/source-code/index.mdx
pages/en/new-design/download/source-code/index.mdx
pages/en/download/source-code/index.mdx
-117
pages/en/new-design/index.mdx
-117
pages/en/new-design/index.mdx
···
1
-
---
2
-
title: Run JavaScript Everywhere
3
-
layout: home.hbs
4
-
---
5
-
6
-
<section>
7
-
<WithBadge section="index" />
8
-
9
-
<div>
10
-
<h1 className="special">Run JavaScript Everywhere</h1>
11
-
12
-
Node.js® is a free, open-source, cross-platform JavaScript runtime
13
-
environment that lets developers create servers, web apps,
14
-
command line tools and scripts.
15
-
16
-
</div>
17
-
18
-
<div>
19
-
<WithNodeRelease status={['Active LTS', 'Maintenance LTS']}>
20
-
{({ release }) => (
21
-
<>
22
-
<DownloadButton release={release}>Download Node.js (LTS)</DownloadButton>
23
-
<small>
24
-
Downloads Node.js <b>{release.versionWithPrefix}</b>
25
-
<sup title="Downloads a Node.js installer for your current platform">1</sup> with long-term support.
26
-
Node.js can also be installed via <a href="/download/package-manager">package managers</a>.
27
-
</small>
28
-
</>
29
-
)}
30
-
</WithNodeRelease>
31
-
<WithNodeRelease status="Current">
32
-
{({ release }) => (
33
-
<small>
34
-
Want new features sooner?
35
-
Get <b>Node.js <DownloadLink release={release}>{release.versionWithPrefix}</DownloadLink></b>
36
-
<sup title="Downloads a Node.js installer for your current platform">1</sup> instead.
37
-
</small>
38
-
)}
39
-
</WithNodeRelease>
40
-
</div>
41
-
</section>
42
-
43
-
<section>
44
-
<div>
45
-
```js displayName="Create an HTTP Server"
46
-
import { createServer } from 'node:http';
47
-
48
-
const server = createServer((req, res) => {
49
-
res.writeHead(200, { 'Content-Type': 'text/plain' });
50
-
res.end('Hello World!\n');
51
-
});
52
-
53
-
// starts a simple http server locally on port 3000
54
-
server.listen(3000, '127.0.0.1', () => {
55
-
console.log('Listening on 127.0.0.1:3000');
56
-
});
57
-
```
58
-
59
-
```js displayName="Write Tests"
60
-
import assert from 'node:assert';
61
-
import test from 'node:test';
62
-
63
-
test('that 1 is equal 1', () => {
64
-
assert.strictEqual(1, 1);
65
-
});
66
-
67
-
test('that throws as 1 is not equal 2', () => {
68
-
// throws an exception because 1 != 2
69
-
assert.strictEqual(1, 2);
70
-
});
71
-
```
72
-
73
-
```js displayName="Read and Hash a File"
74
-
import { createHash } from 'node:crypto';
75
-
import { readFile } from 'node:fs/promises';
76
-
77
-
const hasher = createHash('sha1');
78
-
const fileContent = await readFile('./package.json');
79
-
80
-
hasher.setEncoding('hex');
81
-
hasher.write(fileContent);
82
-
hasher.end();
83
-
84
-
const fileHash = hasher.read();
85
-
```
86
-
87
-
```js displayName="Read Streams"
88
-
import { createReadStream, createWriteStream } from 'node:fs';
89
-
90
-
const res = await fetch('https://nodejs.org/dist/index.json');
91
-
const json = await res.json(); // yields a json object
92
-
93
-
const readableStream = createReadStream('./package.json');
94
-
const writableStream = createWriteStream('./package2.json');
95
-
96
-
readableStream.setEncoding('utf8');
97
-
98
-
readableStream.on('data', chunk => writableStream.write(chunk));
99
-
```
100
-
101
-
```js displayName="Work with Threads"
102
-
import { Worker, isMainThread,
103
-
workerData, parentPort } from 'node:worker_threads';
104
-
105
-
if (isMainThread) {
106
-
const data = 'some data';
107
-
const worker = new Worker(import.meta.filename, { workerData: data });
108
-
worker.on('message', msg => console.log('Reply from Thread:', msg));
109
-
} else {
110
-
const source = workerData;
111
-
parentPort.postMessage(btoa(source.toUpperCase()));
112
-
}
113
-
```
114
-
115
-
</div>
116
-
Learn more what Node.js is able to offer with our [Learning materials](/learn).
117
-
</section>
styles/new/base.css
styles/base.css
styles/new/base.css
styles/base.css
styles/new/effects.css
styles/effects.css
styles/new/effects.css
styles/effects.css
styles/new/index.css
styles/index.css
styles/new/index.css
styles/index.css
styles/new/markdown.css
styles/markdown.css
styles/new/markdown.css
styles/markdown.css
-121
styles/old/base.css
-121
styles/old/base.css
···
1
-
html {
2
-
background-color: $white;
3
-
box-sizing: border-box;
4
-
color: $node-gray;
5
-
font-size: 20px;
6
-
font-weight: 400;
7
-
line-height: 1.5;
8
-
margin: 0;
9
-
}
10
-
11
-
header,
12
-
#main,
13
-
footer {
14
-
display: flex;
15
-
}
16
-
17
-
h1,
18
-
h2,
19
-
h3,
20
-
h4,
21
-
h5 {
22
-
font-weight: 700;
23
-
}
24
-
25
-
h2 {
26
-
font-size: 1.3em;
27
-
}
28
-
29
-
a,
30
-
a:link,
31
-
a:active {
32
-
border-radius: 5px;
33
-
color: $node-green;
34
-
text-decoration: none;
35
-
}
36
-
37
-
a:hover {
38
-
background-color: $node-green;
39
-
color: $white;
40
-
41
-
code {
42
-
background-color: transparent;
43
-
color: $white;
44
-
}
45
-
}
46
-
47
-
a.imagelink {
48
-
display: inline-block;
49
-
50
-
&:hover {
51
-
background-color: transparent;
52
-
}
53
-
}
54
-
55
-
strong,
56
-
b {
57
-
font-weight: 600;
58
-
}
59
-
60
-
p {
61
-
a {
62
-
@mixin padded-link 2px;
63
-
}
64
-
}
65
-
66
-
img {
67
-
border: none;
68
-
display: block;
69
-
height: auto;
70
-
max-width: 100%;
71
-
}
72
-
73
-
code {
74
-
border-radius: 3px;
75
-
font-family: Consolas, Monaco, 'Andale Mono', monospace;
76
-
font-size: 14px;
77
-
padding: 0.2em 0.4em;
78
-
}
79
-
80
-
pre,
81
-
code {
82
-
background-color: #2e3440ff;
83
-
border-radius: 3px;
84
-
color: $white;
85
-
}
86
-
87
-
pre {
88
-
padding: 0.75em 1.2em;
89
-
90
-
code {
91
-
display: grid;
92
-
overflow-x: auto;
93
-
padding: 1em;
94
-
}
95
-
}
96
-
97
-
blockquote {
98
-
margin: 0;
99
-
padding: 0 1em;
100
-
position: relative;
101
-
102
-
&::before {
103
-
background-color: rgb(0 0 0 / 14%);
104
-
content: '';
105
-
display: block;
106
-
height: 100%;
107
-
left: 0;
108
-
position: absolute;
109
-
top: 0;
110
-
width: 6px;
111
-
}
112
-
}
113
-
114
-
iframe {
115
-
border: none;
116
-
}
117
-
118
-
[data-theme='light'] .dark-mode-only,
119
-
[data-theme='dark'] .light-mode-only {
120
-
display: none;
121
-
}
-140
styles/old/index.css
-140
styles/old/index.css
···
1
-
@charset "utf-8";
2
-
3
-
@import 'tailwindcss/utilities';
4
-
5
-
@import 'variables';
6
-
@import 'base';
7
-
@import 'utils';
8
-
@import 'layout/sticky-footer';
9
-
@import 'layout/grid';
10
-
@import 'layout/main';
11
-
@import 'layout/lists';
12
-
@import 'layout/dark-theme';
13
-
@import 'page-modules/jsfoundation';
14
-
@import 'page-modules/header';
15
-
@import 'page-modules/footer';
16
-
@import 'page-modules/home';
17
-
@import 'page-modules/blog-index';
18
-
@import 'page-modules/blog-post';
19
-
@import 'page-modules/download';
20
-
@import 'page-modules/scrollToTop';
21
-
@import 'page-modules/anchorLinks';
22
-
@import 'page-modules/prev-next-navigation';
23
-
24
-
article a {
25
-
word-break: break-word;
26
-
}
27
-
28
-
.intro {
29
-
font-size: 38px;
30
-
line-height: 1.2;
31
-
margin-top: 140px;
32
-
33
-
h1 {
34
-
font-size: inherit;
35
-
margin-bottom: 15px;
36
-
37
-
+ p {
38
-
margin-top: 0;
39
-
}
40
-
}
41
-
42
-
span {
43
-
color: $light-gray;
44
-
display: block;
45
-
}
46
-
}
47
-
48
-
#main {
49
-
.has-side-nav {
50
-
nav {
51
-
margin-top: 1.5em;
52
-
min-width: 200px;
53
-
max-width: 250px;
54
-
55
-
ul {
56
-
list-style-type: none;
57
-
margin: 0;
58
-
padding: 0;
59
-
}
60
-
61
-
li {
62
-
padding: 0.1em 0.5em;
63
-
}
64
-
65
-
a {
66
-
display: block;
67
-
line-height: 1;
68
-
margin-left: -10px;
69
-
margin-right: -10px;
70
-
padding: 5px 10px;
71
-
72
-
&.active,
73
-
&.active:hover {
74
-
background-color: $active-green;
75
-
color: $white;
76
-
}
77
-
}
78
-
}
79
-
80
-
article {
81
-
margin: 0 20px;
82
-
overflow: hidden;
83
-
flex: 1 1;
84
-
}
85
-
}
86
-
}
87
-
88
-
.edit-link {
89
-
float: right;
90
-
font-size: 0.9em;
91
-
margin: 0.5em 0;
92
-
}
93
-
94
-
.color-lightgray {
95
-
color: $light-gray;
96
-
}
97
-
98
-
a:hover .color-lightgray {
99
-
color: $white;
100
-
}
101
-
102
-
.no-padding {
103
-
padding: 0;
104
-
}
105
-
106
-
.highlight-box {
107
-
background-color: $light-gray3;
108
-
border-radius: 2px;
109
-
margin-top: 1em;
110
-
padding: 5px 15px;
111
-
112
-
*:first-child {
113
-
margin-top: 0.5rem;
114
-
}
115
-
}
116
-
117
-
@media screen and (max-width: 1002px) {
118
-
#main {
119
-
article {
120
-
ul:not(.no-padding) {
121
-
margin: 0 20px;
122
-
}
123
-
}
124
-
}
125
-
}
126
-
127
-
@media screen and (max-width: 480px) {
128
-
#main {
129
-
.has-side-nav {
130
-
nav {
131
-
max-width: 100%;
132
-
}
133
-
134
-
article {
135
-
margin: 0;
136
-
width: 100%;
137
-
}
138
-
}
139
-
}
140
-
}
-151
styles/old/layout/dark-theme.css
-151
styles/old/layout/dark-theme.css
···
1
-
html[data-theme='dark'] {
2
-
background-color: $dark-black;
3
-
color: $white;
4
-
5
-
.theme-switcher {
6
-
img.light-image {
7
-
display: none;
8
-
}
9
-
10
-
img.dark-image {
11
-
display: block;
12
-
}
13
-
}
14
-
15
-
.blogpost-meta {
16
-
color: $white;
17
-
}
18
-
19
-
#main {
20
-
p,
21
-
h1,
22
-
h2,
23
-
h3 {
24
-
color: $white;
25
-
}
26
-
27
-
a {
28
-
color: $dark-green2;
29
-
30
-
&:hover {
31
-
color: $white;
32
-
}
33
-
34
-
&.active,
35
-
&.active:hover {
36
-
background-color: $active-green;
37
-
color: $white;
38
-
}
39
-
}
40
-
}
41
-
42
-
header,
43
-
.theme-switcher img,
44
-
.lang-picker-toggler img {
45
-
background-color: $dark-black2;
46
-
}
47
-
48
-
header {
49
-
li {
50
-
&::after {
51
-
border-top-color: $dark-black2 !important;
52
-
}
53
-
}
54
-
55
-
.lang-picker {
56
-
background-color: $dark-black2;
57
-
}
58
-
}
59
-
60
-
article {
61
-
p {
62
-
color: $light-gray3 !important;
63
-
}
64
-
65
-
a {
66
-
color: $dark-green2;
67
-
68
-
&:hover {
69
-
background-color: $dark-green2;
70
-
color: $white;
71
-
}
72
-
}
73
-
74
-
li {
75
-
color: $light-gray3;
76
-
}
77
-
78
-
table {
79
-
background-color: $dark-black3;
80
-
81
-
th {
82
-
color: $white-alpha-b3;
83
-
}
84
-
85
-
td {
86
-
color: $white;
87
-
}
88
-
89
-
tr:only-child,
90
-
tr:nth-child(even) {
91
-
background-color: $dark-black2 !important;
92
-
}
93
-
94
-
tr:nth-child(odd) {
95
-
background-color: $black;
96
-
}
97
-
}
98
-
99
-
.highlight-box {
100
-
background-color: $dark-code-background;
101
-
color: $light-gray3;
102
-
}
103
-
}
104
-
105
-
footer {
106
-
@media (max-width: 481px) {
107
-
margin-top: 0 !important;
108
-
}
109
-
110
-
background-color: $dark-black2;
111
-
112
-
.openjsfoundation-footer {
113
-
background-color: $dark-black2;
114
-
}
115
-
}
116
-
117
-
.home-version-banner {
118
-
background-color: #1f2f2b;
119
-
}
120
-
121
-
.download-hero {
122
-
a {
123
-
background-color: $dark-green;
124
-
color: #0aa007;
125
-
126
-
&:hover {
127
-
background-color: #438542;
128
-
}
129
-
}
130
-
131
-
a.is-version * {
132
-
color: $white;
133
-
}
134
-
}
135
-
136
-
.download-matrix td {
137
-
border-color: $light-gray;
138
-
}
139
-
140
-
.blog-index {
141
-
.summary {
142
-
color: $light-gray;
143
-
font-size: 75%;
144
-
margin-left: 1em;
145
-
}
146
-
}
147
-
148
-
.header-background-fill {
149
-
fill: $dark-black2;
150
-
}
151
-
}
-10
styles/old/layout/grid.css
-10
styles/old/layout/grid.css
-27
styles/old/layout/lists.css
-27
styles/old/layout/lists.css
···
1
-
.list-divider-pipe {
2
-
margin: 0;
3
-
padding: 0;
4
-
5
-
li {
6
-
display: inline-block;
7
-
8
-
+ li::before {
9
-
color: $light-gray;
10
-
content: '|';
11
-
padding: 0 0.3em 0 0.1em;
12
-
}
13
-
}
14
-
}
15
-
16
-
@media screen and (max-width: 480px) {
17
-
nav {
18
-
.list-divider-pipe {
19
-
margin-bottom: 1rem;
20
-
overflow: hidden;
21
-
22
-
li + li::before {
23
-
display: none;
24
-
}
25
-
}
26
-
}
27
-
}
-28
styles/old/layout/main.css
-28
styles/old/layout/main.css
···
1
-
#main {
2
-
.container {
3
-
display: block;
4
-
}
5
-
6
-
.has-side-nav.container {
7
-
flex-direction: row;
8
-
display: flex;
9
-
}
10
-
}
11
-
12
-
@media screen and (max-width: 1002px) {
13
-
#main {
14
-
.container {
15
-
margin: 1em 20px;
16
-
width: calc(100% - 40px);
17
-
}
18
-
}
19
-
}
20
-
21
-
@media screen and (max-width: 480px) {
22
-
#main {
23
-
.container,
24
-
.has-side-nav.container {
25
-
display: block;
26
-
}
27
-
}
28
-
}
-28
styles/old/page-modules/anchorLinks.css
-28
styles/old/page-modules/anchorLinks.css
···
1
-
.anchor {
2
-
background: none;
3
-
color: $light-gray2;
4
-
padding: 0 0.25em;
5
-
float: right;
6
-
7
-
&:link,
8
-
&:active,
9
-
&:hover {
10
-
background: inherit;
11
-
color: $light-gray2;
12
-
}
13
-
14
-
&:focus::before {
15
-
content: '#';
16
-
}
17
-
}
18
-
19
-
h1,
20
-
h2,
21
-
h3,
22
-
h4,
23
-
h5,
24
-
h6 {
25
-
&:hover > .anchor::before {
26
-
content: '#';
27
-
}
28
-
}
-34
styles/old/page-modules/blog-index.css
-34
styles/old/page-modules/blog-index.css
···
1
-
.blog-index {
2
-
list-style: none;
3
-
padding: 0;
4
-
5
-
time {
6
-
color: $light-gray;
7
-
margin-right: 1em;
8
-
}
9
-
10
-
.summary {
11
-
font-size: 75%;
12
-
margin-left: 1em;
13
-
}
14
-
}
15
-
16
-
nav.pagination {
17
-
a {
18
-
@mixin padded-link 2px;
19
-
}
20
-
}
21
-
22
-
@media screen and (max-width: 700px) {
23
-
.blog-index,
24
-
.dark .blog-index {
25
-
.summary {
26
-
margin-left: 0;
27
-
28
-
p {
29
-
overflow: hidden;
30
-
text-overflow: ellipsis;
31
-
}
32
-
}
33
-
}
34
-
}
-12
styles/old/page-modules/blog-post.css
-12
styles/old/page-modules/blog-post.css
-312
styles/old/page-modules/download.css
-312
styles/old/page-modules/download.css
···
1
-
.download-table-currentpage {
2
-
background-color: $node-green;
3
-
color: $white;
4
-
}
5
-
6
-
.download-header {
7
-
h1 {
8
-
float: left;
9
-
margin-bottom: -1rem;
10
-
width: 40%;
11
-
}
12
-
13
-
ul {
14
-
float: right;
15
-
margin-top: 2rem;
16
-
text-align: right;
17
-
width: 40%;
18
-
}
19
-
}
20
-
21
-
.download-header::after {
22
-
clear: both;
23
-
content: '';
24
-
display: block;
25
-
}
26
-
27
-
.download-hero {
28
-
margin-bottom: 1em;
29
-
30
-
ul {
31
-
display: flex;
32
-
list-style: none;
33
-
margin: 0;
34
-
overflow: hidden;
35
-
text-align: center;
36
-
}
37
-
38
-
li {
39
-
display: flex;
40
-
flex-basis: 200px;
41
-
flex-grow: 1;
42
-
}
43
-
44
-
a {
45
-
background: $light-green;
46
-
border-radius: 0 !important;
47
-
color: $active-green;
48
-
display: block;
49
-
padding-top: 1em;
50
-
width: 100%;
51
-
}
52
-
53
-
.download-logo {
54
-
display: block;
55
-
fill: $node-green;
56
-
margin: 0 auto;
57
-
}
58
-
59
-
p {
60
-
margin: 1em 0 0;
61
-
padding-bottom: 1em;
62
-
}
63
-
64
-
a:hover {
65
-
background: $node-green;
66
-
color: $white;
67
-
68
-
.download-logo {
69
-
fill: $white;
70
-
}
71
-
}
72
-
73
-
a:active {
74
-
background: $active-green;
75
-
color: $white;
76
-
}
77
-
78
-
.download-version-toggle {
79
-
border-top-left-radius: 5px;
80
-
border-top-right-radius: 5px;
81
-
display: flex;
82
-
flex-wrap: nowrap;
83
-
84
-
a {
85
-
border-radius: 0;
86
-
padding: 5px 2px;
87
-
}
88
-
89
-
a:hover,
90
-
a:active,
91
-
a.is-version {
92
-
background: $node-green;
93
-
color: $white;
94
-
}
95
-
96
-
a.is-version {
97
-
background: $active-green;
98
-
color: $light-green;
99
-
}
100
-
101
-
.title {
102
-
font-size: 1.5em;
103
-
line-height: 1;
104
-
}
105
-
106
-
.tag {
107
-
font-size: 0.8em;
108
-
}
109
-
}
110
-
111
-
.download-platform {
112
-
border-bottom-left-radius: 5px;
113
-
border-bottom-right-radius: 5px;
114
-
border-top: 2px solid $node-green;
115
-
}
116
-
}
117
-
118
-
.download-matrix {
119
-
margin-bottom: 1.5rem;
120
-
121
-
th {
122
-
text-align: left;
123
-
width: 33%;
124
-
}
125
-
126
-
td {
127
-
border: 1px solid $light-gray2;
128
-
129
-
a,
130
-
span {
131
-
background: none;
132
-
display: block;
133
-
font-size: 0.8em;
134
-
height: 100%;
135
-
text-align: center;
136
-
width: 100%;
137
-
}
138
-
139
-
a:hover,
140
-
a:active {
141
-
background: $node-green;
142
-
color: $white;
143
-
}
144
-
}
145
-
}
146
-
147
-
h5.download-table-previous-releases-header {
148
-
margin-bottom: 5px;
149
-
}
150
-
151
-
.download-table {
152
-
border: 1px solid $light-gray2;
153
-
border-spacing: 0;
154
-
font-size: small;
155
-
text-align: center;
156
-
157
-
td {
158
-
padding: 5px;
159
-
}
160
-
161
-
> thead {
162
-
font-weight: 600;
163
-
164
-
th:last-child {
165
-
text-align: left;
166
-
padding-left: 1.5rem;
167
-
}
168
-
}
169
-
170
-
> tbody {
171
-
td {
172
-
border-top: 1px solid $light-gray2;
173
-
}
174
-
175
-
tr:nth-child(odd) {
176
-
background-color: $light-gray3;
177
-
}
178
-
179
-
tr:nth-child(even) {
180
-
background-color: $white;
181
-
}
182
-
}
183
-
}
184
-
185
-
td.download-table-last {
186
-
text-align: right;
187
-
188
-
> a {
189
-
padding: 0 10px;
190
-
}
191
-
}
192
-
193
-
@media (max-width: 700px) {
194
-
.download-hero {
195
-
ul {
196
-
display: block;
197
-
text-align: left;
198
-
}
199
-
200
-
li {
201
-
display: block;
202
-
text-align: center;
203
-
}
204
-
205
-
.download-version-toggle {
206
-
display: flex;
207
-
padding-right: 4px;
208
-
209
-
li {
210
-
display: inline-block;
211
-
flex-basis: 160px;
212
-
}
213
-
214
-
.tag {
215
-
font-size: 0.6em;
216
-
}
217
-
}
218
-
}
219
-
220
-
.download-matrix {
221
-
display: block;
222
-
223
-
th {
224
-
display: block;
225
-
width: 100%;
226
-
}
227
-
228
-
tr {
229
-
display: block;
230
-
margin-bottom: 1em;
231
-
}
232
-
233
-
td {
234
-
border: none;
235
-
display: block;
236
-
237
-
a {
238
-
text-align: left;
239
-
}
240
-
}
241
-
}
242
-
243
-
.download-table {
244
-
border: none;
245
-
246
-
> thead {
247
-
display: none;
248
-
}
249
-
250
-
tr {
251
-
display: block;
252
-
margin-bottom: 10px;
253
-
}
254
-
255
-
td {
256
-
display: block;
257
-
text-align: right;
258
-
}
259
-
260
-
td:last-child {
261
-
border-bottom: 0;
262
-
}
263
-
264
-
td::before {
265
-
content: attr(data-label);
266
-
float: left;
267
-
font-weight: 600;
268
-
}
269
-
270
-
> thead > tr > th,
271
-
> tbody > tr > th,
272
-
> tfoot > tr > th,
273
-
> thead > tr > td,
274
-
> tbody > tr > td,
275
-
> tfoot > tr > td,
276
-
> tbody td {
277
-
border: none;
278
-
}
279
-
}
280
-
281
-
.download-table > tbody td {
282
-
border: none;
283
-
}
284
-
285
-
td.download-table-last {
286
-
text-align: center;
287
-
}
288
-
}
289
-
290
-
@media screen and (max-width: 700px) {
291
-
.download-matrix {
292
-
display: revert;
293
-
}
294
-
295
-
.download-matrix ~ section ul {
296
-
padding: 0 20px;
297
-
}
298
-
}
299
-
300
-
@media (max-width: 320px) {
301
-
.download-hero {
302
-
.download-version-toggle {
303
-
li {
304
-
font-size: 1em;
305
-
}
306
-
307
-
.tag {
308
-
font-size: 0.4em;
309
-
}
310
-
}
311
-
}
312
-
}
-227
styles/old/page-modules/header.css
-227
styles/old/page-modules/header.css
···
1
-
header,
2
-
.theme-switcher img,
3
-
.lang-picker-toggler img {
4
-
background-color: $node-gray;
5
-
}
6
-
7
-
header {
8
-
position: relative;
9
-
text-align: center;
10
-
11
-
> .container {
12
-
overflow: visible;
13
-
}
14
-
15
-
li {
16
-
position: relative;
17
-
}
18
-
19
-
nav {
20
-
cursor: default;
21
-
22
-
a,
23
-
a:link,
24
-
a:active {
25
-
color: $light-gray2 !important;
26
-
font-size: 14px;
27
-
padding: 0 8px;
28
-
text-transform: uppercase;
29
-
}
30
-
31
-
a:hover {
32
-
background-color: transparent;
33
-
text-decoration: underline;
34
-
}
35
-
}
36
-
37
-
.header-background-fill {
38
-
fill: $node-gray;
39
-
}
40
-
41
-
.switchers {
42
-
align-items: center;
43
-
bottom: 0;
44
-
display: flex;
45
-
position: absolute;
46
-
right: 0;
47
-
top: 0;
48
-
}
49
-
50
-
.theme-switcher {
51
-
border: none;
52
-
cursor: pointer;
53
-
margin: 0 8px 0 0;
54
-
padding: 0;
55
-
56
-
img.light-image {
57
-
display: block;
58
-
}
59
-
60
-
img.dark-image {
61
-
display: none;
62
-
}
63
-
}
64
-
65
-
.lang-picker-toggler {
66
-
border: none;
67
-
color: $light-gray2;
68
-
cursor: pointer;
69
-
margin: 0 8px 0 0;
70
-
padding: 0;
71
-
}
72
-
73
-
.lang-picker {
74
-
background: $node-gray;
75
-
list-style-type: none;
76
-
margin: 0;
77
-
max-height: 400px;
78
-
overflow: auto;
79
-
padding: 0;
80
-
position: absolute;
81
-
right: 0;
82
-
top: 100%;
83
-
z-index: 1;
84
-
85
-
a {
86
-
color: $light-gray2;
87
-
}
88
-
89
-
li {
90
-
padding-bottom: 0;
91
-
92
-
a {
93
-
background-color: transparent;
94
-
border: none;
95
-
color: $light-gray2 !important;
96
-
cursor: pointer;
97
-
display: inline-block;
98
-
font-family: inherit;
99
-
font-size: 14px;
100
-
line-height: 1.5;
101
-
margin: 0 auto;
102
-
padding: 0.5em 1em;
103
-
text-transform: uppercase;
104
-
105
-
&:focus,
106
-
&:hover {
107
-
background-color: $node-green;
108
-
text-decoration: underline;
109
-
}
110
-
}
111
-
}
112
-
}
113
-
114
-
.logo {
115
-
align-items: center;
116
-
bottom: 0;
117
-
display: flex;
118
-
justify-content: space-evenly;
119
-
left: 0;
120
-
margin: 0 10px 8px;
121
-
position: absolute;
122
-
top: 0;
123
-
124
-
img {
125
-
margin-bottom: -4px;
126
-
}
127
-
128
-
&:hover {
129
-
background-color: transparent;
130
-
text-decoration: underline;
131
-
}
132
-
}
133
-
}
134
-
135
-
@media screen and (min-width: 481px) {
136
-
header {
137
-
ul {
138
-
min-height: 42px;
139
-
140
-
li {
141
-
margin-top: 4px;
142
-
143
-
$border-width: 14px;
144
-
145
-
&:has(a.active)::after {
146
-
border: solid transparent;
147
-
border-top-color: $node-gray;
148
-
border-width: $border-width;
149
-
content: ' ';
150
-
height: 0;
151
-
left: 50%;
152
-
margin-left: calc(-$border-width * 0.5);
153
-
pointer-events: none;
154
-
position: absolute;
155
-
top: 100%;
156
-
width: 0;
157
-
}
158
-
159
-
&:has(a.active):first-child::after {
160
-
margin-left: -$border-width;
161
-
}
162
-
}
163
-
}
164
-
165
-
a,
166
-
a:link,
167
-
a:active {
168
-
padding: 0 8px;
169
-
}
170
-
}
171
-
}
172
-
173
-
@media screen and (max-width: 1000px) and (min-width: 743px),
174
-
screen and (max-width: 881px) {
175
-
header {
176
-
.switchers {
177
-
justify-content: center;
178
-
margin: 10px 0 16px;
179
-
position: unset;
180
-
}
181
-
182
-
.lang-picker {
183
-
li {
184
-
float: left;
185
-
margin: 0;
186
-
padding: 0;
187
-
width: 50%;
188
-
}
189
-
}
190
-
191
-
.logo {
192
-
justify-content: center;
193
-
margin: 10px 0 16px;
194
-
position: unset;
195
-
}
196
-
}
197
-
}
198
-
199
-
@media screen and (max-width: 480px) {
200
-
header {
201
-
.switchers {
202
-
justify-content: space-evenly;
203
-
}
204
-
205
-
li {
206
-
float: left;
207
-
margin: 0;
208
-
padding: 0;
209
-
width: 50%;
210
-
}
211
-
212
-
nav {
213
-
margin: 0 20px;
214
-
}
215
-
216
-
a,
217
-
a:link,
218
-
a:active {
219
-
padding: 0;
220
-
}
221
-
222
-
.lang-picker-toggler {
223
-
padding: 0;
224
-
position: relative;
225
-
}
226
-
}
227
-
}
-209
styles/old/page-modules/home.css
-209
styles/old/page-modules/home.css
···
1
-
.home-version {
2
-
color: $gray;
3
-
font-size: 16px;
4
-
padding-top: 10px;
5
-
}
6
-
7
-
.home-version-banner {
8
-
background-color: $light-green;
9
-
border-radius: 2px;
10
-
color: $node-gray;
11
-
font-size: 130%;
12
-
margin-top: 1em;
13
-
padding: 5px 15px;
14
-
15
-
a {
16
-
color: $active-green;
17
-
18
-
&:hover {
19
-
color: $white;
20
-
}
21
-
}
22
-
}
23
-
24
-
.home-secondary-links {
25
-
color: $home-secondary-links-color;
26
-
font-size: 0.9rem;
27
-
28
-
a {
29
-
color: $home-secondary-links-color;
30
-
31
-
&:hover {
32
-
background-color: transparent;
33
-
border-bottom: 1px solid $home-secondary-links-color;
34
-
border-radius: 0;
35
-
}
36
-
}
37
-
}
38
-
39
-
#home-intro {
40
-
margin: 0 auto;
41
-
max-width: calc($body-max-width * 0.75);
42
-
padding: 30px 0;
43
-
text-align: center;
44
-
45
-
h2 {
46
-
margin-bottom: 0;
47
-
}
48
-
}
49
-
50
-
.home-banner {
51
-
opacity: 1;
52
-
transition: opacity 0.2s ease-in-out;
53
-
54
-
&:hover {
55
-
opacity: 0.85;
56
-
}
57
-
58
-
> img {
59
-
border-radius: 10px;
60
-
}
61
-
}
62
-
63
-
.home-downloadblock {
64
-
display: inline-block;
65
-
margin: 0 8px;
66
-
}
67
-
68
-
.home-downloadbutton {
69
-
background-color: $active-green;
70
-
border-radius: 10px;
71
-
color: $white !important;
72
-
display: block;
73
-
font-size: 30px;
74
-
font-weight: 400;
75
-
margin: 10px 4px;
76
-
padding: 0.2em 0.6em;
77
-
transition: background-color 0.2s ease-in-out;
78
-
79
-
&:hover {
80
-
background-color: $node-green;
81
-
}
82
-
83
-
small {
84
-
display: block;
85
-
font-size: 1rem;
86
-
}
87
-
}
88
-
89
-
/**
90
-
* BLM CTA button styles.
91
-
*/
92
-
93
-
.home-blacklivesmatterblock {
94
-
display: block;
95
-
font-size: 16px;
96
-
height: 4rem;
97
-
position: relative;
98
-
}
99
-
100
-
.home-blacklivesmatterbutton {
101
-
color: $white !important;
102
-
display: block;
103
-
font-size: 130%;
104
-
font-weight: 400;
105
-
left: 50%;
106
-
max-width: 100%;
107
-
padding: 0.5em 20%;
108
-
position: absolute;
109
-
top: 50%;
110
-
transform: translateX(-50%) translateY(-50%);
111
-
transition: padding 0.2s ease-in-out;
112
-
113
-
&:active,
114
-
&:focus,
115
-
&:hover {
116
-
padding: calc(0.5em * 1.2) calc(20% * 1.2);
117
-
}
118
-
119
-
small {
120
-
display: block;
121
-
font-size: 1rem;
122
-
}
123
-
}
124
-
125
-
/**
126
-
* Accessible button role styles (copypasta) integrated into site color scheme.
127
-
* @author W3C
128
-
* @see https://www.w3.org/TR/wai-aria-practices/examples/button/button.html
129
-
*/
130
-
131
-
[role='button'] {
132
-
background-color: hsl(0deg 0% 31%);
133
-
background-image: linear-gradient(
134
-
to bottom,
135
-
hsl(0deg 0% 33%),
136
-
hsl(0deg 0% 27%)
137
-
);
138
-
border: 1px solid hsl(0deg 0% 39%);
139
-
border-radius: 5px;
140
-
box-shadow: 0 1px 2px hsl(0deg 0% 45%);
141
-
color: #fff;
142
-
text-shadow: 0 -1px 1px hsl(0deg 0% 15%);
143
-
}
144
-
145
-
[role='button']:hover {
146
-
background-color: hsl(0deg 0% 21%);
147
-
background-image: linear-gradient(
148
-
to bottom,
149
-
hsl(0deg 0% 23%),
150
-
hsl(0deg 0% 17%)
151
-
);
152
-
border-color: hsl(0deg 0% 19%);
153
-
cursor: pointer;
154
-
}
155
-
156
-
[role='button']:focus {
157
-
outline: none;
158
-
}
159
-
160
-
[role='button']:focus::before {
161
-
border: 3px solid hsl(0deg 0% 39%);
162
-
163
-
/* button border radius + outline width + offset */
164
-
border-radius: calc(5px + 3px + 3px);
165
-
content: '';
166
-
inset: calc(-1px - 3px - 3px) calc(-1px - 3px - 3px) calc(-1px - 3px - 3px)
167
-
calc(-1px - 3px - 3px);
168
-
position: absolute;
169
-
170
-
/* button border width - outline width - offset */
171
-
z-index: -1;
172
-
}
173
-
174
-
[role='button']:active {
175
-
background-color: hsl(0deg 0% 11%);
176
-
background-image: linear-gradient(
177
-
to bottom,
178
-
hsl(0deg 0% 33%),
179
-
hsl(0deg 0% 27%)
180
-
);
181
-
border-color: hsl(0deg 0% 29%);
182
-
box-shadow: inset 0 3px 5px 1px hsl(0deg 0% 10%);
183
-
}
184
-
185
-
[role='button'][aria-pressed] {
186
-
background-color: hsl(0deg 0% 31%);
187
-
background-image: linear-gradient(
188
-
to bottom,
189
-
hsl(0deg 0% 33%),
190
-
hsl(0deg 0% 27%)
191
-
);
192
-
border-color: hsl(0deg 0% 29%);
193
-
box-shadow: 0 1px 2px hsl(0deg 0% 35%);
194
-
text-shadow: 0 -1px 1px hsl(0deg 0% 5%);
195
-
}
196
-
197
-
[role='button'][aria-pressed]:hover {
198
-
background-color: hsl(0deg 0% 31%);
199
-
background-image: linear-gradient(
200
-
to bottom,
201
-
hsl(0deg 0% 13%),
202
-
hsl(0deg 0% 7%)
203
-
);
204
-
border-color: hsl(0deg 0% 9%);
205
-
}
206
-
207
-
[role='button'][aria-pressed]:focus::before {
208
-
border-color: hsl(0deg 0% 29%);
209
-
}
-88
styles/old/page-modules/jsfoundation.css
-88
styles/old/page-modules/jsfoundation.css
···
1
-
.openjsfoundation-footer {
2
-
background: $node-gray;
3
-
color: $white;
4
-
direction: ltr;
5
-
float: left;
6
-
font-size: small;
7
-
padding: 1em 20px;
8
-
text-align: center;
9
-
10
-
p + p {
11
-
font-size: 15px;
12
-
}
13
-
}
14
-
15
-
.openjsfoundation-footer-edit {
16
-
display: inline;
17
-
font-size: 15px;
18
-
}
19
-
20
-
.openjsfoundation-footer-links {
21
-
display: inline;
22
-
}
23
-
24
-
.issue-link-container {
25
-
align-items: center;
26
-
display: flex;
27
-
}
28
-
29
-
.issue-link {
30
-
margin-left: auto;
31
-
min-width: 330px;
32
-
text-align: left;
33
-
}
34
-
35
-
.help {
36
-
color: $white;
37
-
font-size: 14px;
38
-
margin-top: 3em;
39
-
width: 40%;
40
-
}
41
-
42
-
@media (min-width: 280px) {
43
-
.help {
44
-
margin-left: 10%;
45
-
}
46
-
}
47
-
48
-
@media (min-width: 320px) {
49
-
.help {
50
-
margin-left: 58%;
51
-
}
52
-
}
53
-
54
-
@media (min-width: 500px) {
55
-
.help {
56
-
margin-left: 65%;
57
-
}
58
-
}
59
-
60
-
@media (min-width: 768px) {
61
-
.help {
62
-
margin-left: 70%;
63
-
}
64
-
}
65
-
66
-
@media screen and (max-width: 700px) {
67
-
.issue-link-container {
68
-
flex-wrap: wrap;
69
-
}
70
-
71
-
.issue-link {
72
-
margin: 1em 0 0;
73
-
min-width: 0;
74
-
text-align: start;
75
-
}
76
-
}
77
-
78
-
@media screen and (max-width: 480px) {
79
-
.openjsfoundation-footer {
80
-
padding: 3em 20px;
81
-
width: auto;
82
-
}
83
-
84
-
.help {
85
-
margin-left: auto;
86
-
width: auto;
87
-
}
88
-
}
-7
styles/old/page-modules/scrollToTop.css
-7
styles/old/page-modules/scrollToTop.css
-39
styles/old/utils.css
-39
styles/old/utils.css
···
1
-
.bg-white {
2
-
background-color: $white !important;
3
-
}
4
-
5
-
.bg-node-gray {
6
-
background-color: $node-gray !important;
7
-
}
8
-
9
-
.table-no-border-no-padding {
10
-
border-spacing: 0;
11
-
12
-
td {
13
-
padding: 0;
14
-
}
15
-
}
16
-
17
-
.sr-only {
18
-
border: none;
19
-
clip: rect(0, 0, 0, 0);
20
-
height: 1px;
21
-
overflow: hidden;
22
-
padding: 0;
23
-
position: absolute;
24
-
white-space: nowrap;
25
-
width: 1px;
26
-
}
27
-
28
-
.hidden {
29
-
display: none;
30
-
}
31
-
32
-
.full-width {
33
-
width: 100%;
34
-
}
35
-
36
-
small,
37
-
.small {
38
-
font-size: 0.7rem;
39
-
}
-34
styles/old/variables.css
-34
styles/old/variables.css
···
1
-
$body-max-width: 980px;
2
-
3
-
$black: #000;
4
-
$white: #fff;
5
-
$white-alpha-b3: #ffffffb3;
6
-
$node-green: #43853d;
7
-
$light-green: #eaf5e9;
8
-
$active-green: #026e00;
9
-
10
-
$light-gray3: #f0f0f0;
11
-
$light-gray2: #ccc;
12
-
$light-gray: #999;
13
-
$gray: #666;
14
-
$node-gray: #333;
15
-
$home-secondary-links-color: #51744e;
16
-
$black-alpha-80: #00000080;
17
-
$black-alpha-12: #00000012;
18
-
$black-alpha-0f: #0000000f;
19
-
20
-
$dark-black: #090c15;
21
-
$dark-black2: #233056;
22
-
$dark-black3: #23305671;
23
-
$dark-gray: #242424;
24
-
$dark-green: #2c372a;
25
-
$dark-green2: #84ba64;
26
-
$dark-green3: #64de64;
27
-
$dark-code-background: #2c3437;
28
-
29
-
@define-mixin padded-link $padding {
30
-
margin-left: calc($padding * -1);
31
-
margin-right: calc($padding * -1);
32
-
padding-left: $padding;
33
-
padding-right: $padding;
34
-
}
-4
turbo.json
-4
turbo.json
···
16
16
"NEXT_PUBLIC_ORAMA_API_KEY",
17
17
"NEXT_PUBLIC_ORAMA_ENDPOINT",
18
18
"NEXT_PUBLIC_VERCEL_REVALIDATE_TIME",
19
-
"NEXT_PUBLIC_ENABLE_REDESIGN",
20
19
"NEXT_PUBLIC_DATA_URL"
21
20
]
22
21
},
···
40
39
"NEXT_PUBLIC_ORAMA_API_KEY",
41
40
"NEXT_PUBLIC_ORAMA_ENDPOINT",
42
41
"NEXT_PUBLIC_VERCEL_REVALIDATE_TIME",
43
-
"NEXT_PUBLIC_ENABLE_REDESIGN",
44
42
"NEXT_PUBLIC_DATA_URL"
45
43
]
46
44
},
···
58
56
"NEXT_PUBLIC_ORAMA_API_KEY",
59
57
"NEXT_PUBLIC_ORAMA_ENDPOINT",
60
58
"NEXT_PUBLIC_VERCEL_REVALIDATE_TIME",
61
-
"NEXT_PUBLIC_ENABLE_REDESIGN",
62
59
"NEXT_PUBLIC_DATA_URL"
63
60
]
64
61
},
···
82
79
"NEXT_PUBLIC_ORAMA_API_KEY",
83
80
"NEXT_PUBLIC_ORAMA_ENDPOINT",
84
81
"NEXT_PUBLIC_VERCEL_REVALIDATE_TIME",
85
-
"NEXT_PUBLIC_ENABLE_REDESIGN",
86
82
"NEXT_PUBLIC_DATA_URL"
87
83
]
88
84
},
-2
types/features.ts
-2
types/features.ts
+2
-2
types/frontmatter.ts
+2
-2
types/frontmatter.ts
···
1
-
import type { LegacyLayouts } from './layouts';
1
+
import type { Layouts } from './layouts';
2
2
3
3
// @TODO: Extra data from Frontmatter should not be a thing in the future
4
4
// eslint-disable-next-line @typescript-eslint/no-explicit-any
5
5
export interface LegacyFrontMatter extends Record<string, any> {
6
-
layout?: LegacyLayouts;
6
+
layout?: Layouts;
7
7
title?: string;
8
8
labels?: Record<string, string>;
9
9
}
-12
types/layouts.ts
-12
types/layouts.ts
···
1
-
// @TODO: These are the Website Redesign Layouts
2
1
export type Layouts =
3
2
| 'about.hbs'
4
3
| 'home.hbs'
···
8
7
| 'blog-post.hbs'
9
8
| 'search.hbs'
10
9
| 'download.hbs';
11
-
12
-
// @TODO: These are legacy layouts that are going to be replaced with the `nodejs/nodejs.dev` Layouts in the future
13
-
export type LegacyLayouts =
14
-
| 'about.hbs'
15
-
| 'learn.hbs'
16
-
| 'blog-category.hbs'
17
-
| 'blog-post.hbs'
18
-
| 'index.hbs'
19
-
| 'docs.hbs'
20
-
| 'download.hbs'
21
-
| 'page.hbs';
+1
-1
types/release.ts
+1
-1
types/release.ts
···
3
3
import type { NodeRelease } from '@/types/releases';
4
4
import type { UserOS } from '@/types/userOS';
5
5
6
-
export type PackageManager = 'NVM' | 'BREW' | 'DOCKER';
6
+
export type PackageManager = 'NVM' | 'BREW' | 'DOCKER' | 'CHOCO';
7
7
8
8
export interface ReleaseState {
9
9
os: UserOS;
+4
-6
util/downloadUtils.ts
+4
-6
util/downloadUtils.ts
···
1
-
import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs';
2
1
import type { PackageManager } from '@/types/release';
3
2
import type { UserOS } from '@/types/userOS';
4
3
···
33
32
{
34
33
label: 'Brew',
35
34
value: 'BREW' as PackageManager,
35
+
},
36
+
{
37
+
label: 'Chocolatey',
38
+
value: 'CHOCO' as PackageManager,
36
39
},
37
40
{
38
41
label: 'Docker',
···
114
117
// Returns the page, category and subCategoy information to be used in the page
115
118
// from the pathname information on the download pages.
116
119
export const getDownloadCategory = (pathname: string) => {
117
-
/** @deprecated once the website redesign happens remove this code block */
118
-
if (ENABLE_WEBSITE_REDESIGN) {
119
-
pathname = pathname.replace('/new-design', '');
120
-
}
121
-
122
120
const segments = pathname.split('/').filter(Boolean);
123
121
const [, c] = segments;
124
122
+70
-60
util/getNodeDownloadSnippet.ts
+70
-60
util/getNodeDownloadSnippet.ts
···
1
1
import dedent from 'dedent';
2
2
3
+
import type { NodeRelease } from '@/types';
4
+
import type { PackageManager } from '@/types/release';
3
5
import type { UserOS } from '@/types/userOS';
4
6
5
-
export const getNodeDownloadSnippet = (major: number, os: UserOS) => {
7
+
export const getNodeDownloadSnippet = (release: NodeRelease, os: UserOS) => {
8
+
const snippets: Record<PackageManager, string> = {
9
+
NVM: '',
10
+
BREW: '',
11
+
DOCKER: '',
12
+
CHOCO: '',
13
+
};
14
+
6
15
if (os === 'LINUX' || os === 'MAC') {
7
-
const platformSnippets = {
8
-
NVM: dedent`
9
-
# Installs NVM (Node Version Manager)
10
-
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
16
+
snippets.NVM = dedent`
17
+
# installs NVM (Node Version Manager)
18
+
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
11
19
12
-
# Installs Node.js
13
-
nvm install v${major}
20
+
# download and install Node.js
21
+
nvm install ${release.major}
14
22
15
-
# Checks that Node is installed
16
-
node -v
23
+
# verifies the right Node.js version is in the environment
24
+
node -v # should print \`${release.versionWithPrefix}\`
17
25
18
-
# Checks your NPM version
19
-
npm -v`,
20
-
BREW: dedent`
21
-
# Installs Brew (macOS/Linux Package Manager)
22
-
curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash
26
+
# verifies the right NPM version is in the environment
27
+
npm -v # should print \`${release.npm}\``;
23
28
24
-
# Installs Node.js
25
-
brew install node@${major}
29
+
snippets.BREW = dedent`
30
+
# download and installs Homebrew (macOS/Linux Package Manager)
31
+
curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash
26
32
27
-
# Checks that Node is installed
28
-
node -v
33
+
# download and install Node.js
34
+
brew install node@${release.major}
29
35
30
-
# Checks your NPM version
31
-
npm -v`,
32
-
DOCKER: '',
33
-
};
36
+
# verifies the right Node.js version is in the environment
37
+
node -v # should print \`${release.versionWithPrefix}\`
34
38
35
-
if (os === 'MAC') {
36
-
platformSnippets.DOCKER = dedent`
37
-
# Installs Brew (macOS Package Manager)
38
-
curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash
39
+
# verifies the right NPM version is in the environment
40
+
npm -v # should print \`${release.npm}\``;
41
+
}
39
42
40
-
# Installs Docker Desktop
41
-
brew install docker --cask
43
+
if (os === 'MAC') {
44
+
snippets.DOCKER = dedent`
45
+
# installs Homebrew (macOS/Linux Package Manager)
46
+
curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash
42
47
43
-
# Pull Node.js Docker Image
44
-
docker pull node:${major}-${major >= 4 ? 'alpine' : 'slim'}
45
-
`;
46
-
}
48
+
# installs Docker Desktop
49
+
brew install docker --cask
47
50
48
-
return platformSnippets;
51
+
# pulls the Node.js Docker image
52
+
docker pull node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'}
53
+
54
+
# verifies the right Node.js version is in the environment
55
+
docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} node -v # should print \`${release.versionWithPrefix}\`
56
+
57
+
# verifies the right NPM version is in the environment
58
+
docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} npm -v # should print \`${release.npm}\``;
49
59
}
50
60
51
61
if (os === 'WIN') {
52
-
return {
53
-
NVM: dedent`
54
-
# Installs Chocolatey (Windows Package Manager)
55
-
Set-ExecutionPolicy Bypass -Scope Process -Force;
56
-
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
57
-
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
62
+
snippets.CHOCO = dedent`
63
+
# installs Chocolatey (Windows Package Manager)
64
+
Set-ExecutionPolicy Bypass -Scope Process -Force;
65
+
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
66
+
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'));
67
+
68
+
# download and install Node.js
69
+
choco install nodejs --version="${release.version}"
58
70
59
-
# Installs NVM (Node Version Manager)
60
-
choco install nvm
71
+
# verifies the right Node.js version is in the environment
72
+
node -v # should print \`${release.versionWithPrefix}\`
61
73
62
-
# Installs Node.js
63
-
nvm install v${major}
74
+
# verifies the right NPM version is in the environment
75
+
npm -v # should print \`${release.npm}\``;
76
+
77
+
snippets.DOCKER = dedent`
78
+
# installs Chocolatey (Windows Package Manager)
79
+
Set-ExecutionPolicy Bypass -Scope Process -Force;
80
+
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
81
+
iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'));
64
82
65
-
# Checks that Node is installed
66
-
node -v
83
+
# installs Docker Desktop
84
+
choco install docker-desktop
67
85
68
-
# Checks your NPM version
69
-
npm -v`,
70
-
DOCKER: dedent`
71
-
# Installs Chocolatey (Windows Package Manager)
72
-
Set-ExecutionPolicy Bypass -Scope Process -Force;
73
-
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072;
74
-
iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1'));
86
+
# pulls the Node.js Docker image
87
+
docker pull node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'}
75
88
76
-
# Installs Docker Desktop
77
-
choco install docker-desktop
89
+
# verifies the right Node.js version is in the environment
90
+
docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} node -v # should print \`${release.versionWithPrefix}\`
78
91
79
-
# Pull Node.js Docker Image
80
-
docker pull node:${major}-${major >= 4 ? 'alpine' : 'slim'}
81
-
`,
82
-
BREW: '',
83
-
};
92
+
# verifies the right NPM version is in the environment
93
+
docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} npm -v # should print \`${release.npm}\``;
84
94
}
85
95
86
-
return { NVM: '', BREW: '', DOCKER: '' };
96
+
return snippets;
87
97
};