Skip to content

Commit 047e3c9

Browse files
committed
chore: resolve conflict
2 parents 672e2cb + 90afad3 commit 047e3c9

File tree

104 files changed

+8557
-5832
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

104 files changed

+8557
-5832
lines changed

.github/workflows/dependency-review.yml

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ on:
1313
branches:
1414
- main
1515

16+
# Cancel any runs on the same branch
17+
concurrency:
18+
group: ${{ github.workflow }}-${{ github.ref }}
19+
cancel-in-progress: true
20+
1621
permissions:
1722
contents: read
1823

.github/workflows/translations-pr.yml

+5
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ on:
1515
- 'packages/i18n/locales/*.json'
1616
- '!packages/i18n/locales/en.json'
1717

18+
# Cancel any runs on the same branch
19+
concurrency:
20+
group: ${{ github.workflow }}-${{ github.ref }}
21+
cancel-in-progress: true
22+
1823
permissions:
1924
actions: read
2025

CONTRIBUTING.md

+97
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ Thank you for your interest in contributing to the Node.js Website. Before you p
1010
- [Commit Guidelines](#commit-guidelines)
1111
- [Pull Request Policy](#pull-request-policy)
1212
- [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin-11)
13+
- [Adding a Learn Page](#adding-a-learn-page)
1314

1415
## Contributing
1516

@@ -241,3 +242,99 @@ By contributing to this project, I certify that:
241242
[Conventional Commits]: https://www.conventionalcommits.org/
242243
[Commit Signing]: https://docs.github.com/en/authentication/managing-commit-signature-verification/signing-commits
243244
[Husky]: https://typicode.github.io/husky/
245+
246+
## Adding a Learn Page
247+
248+
Since the redesign of the website, we have a new section called 'Learn'. This is intended to provide a more explanatory set of resources than the API docs, which are designed purely to explain the available APIs.
249+
250+
The Learn section is separate from the API docs and is intended to provide a more narrative, tutorial style set of resources. This is a place where we can provide more context and guidance on how to use the APIs and how to build applications with them.
251+
252+
The Learn section is also divided into several sub-categories. Note that the sub-categories must be on the same topic.
253+
254+
### Structure of the Learn section
255+
256+
The file structure of the Learn section is as follows:
257+
258+
```
259+
site/
260+
├─ pages/
261+
│ ├─ en/
262+
│ │ ├─ learn/
263+
│ │ │ ├─ sub-categories/
264+
│ │ │ │ ├─ article.md
265+
```
266+
267+
The frontmatter of the `article.md` file should look like this:
268+
269+
```yaml
270+
title: A super cool title
271+
layout: learn
272+
authors: github_username, another_github_username
273+
```
274+
275+
A little bit of explanation about the frontmatter:
276+
277+
- `title`: The title of the article. This will be displayed as the title of the page. We recommend that you use the same title as the navigation entry. How to enter navigation entries is explained later in this document.
278+
- `layout`: This must be set to `learn` so that the new article has the same style as other Learn pages.
279+
- `authors`: A list of the GitHub usernames of the authors of the article. This is used to display the authors' profile pictures on the page. The frontmatter must always have the `github_username` followed by `, `. The comma and space is important.
280+
281+
### Modify the navigation
282+
283+
The data of the navigation is stored in app/site/navigation.json. To add a new entry to the navigation, you need to add a new object to the sideNavigation.learn.
284+
285+
```json
286+
{
287+
"sideNavigation": {
288+
"learn": [
289+
{
290+
"label": "Sub-category",
291+
"items": {
292+
"article": {
293+
"link": "/learn/sub-category/article",
294+
"label": "components.navigation.learn.sub-category.article"
295+
}
296+
}
297+
}
298+
]
299+
}
300+
}
301+
```
302+
303+
The `label` key is used to display the title of the article in the navigation. To add a new i18n key we recommend you to read [the translation guide](./TRANSLATION.md#adding-new-translation-keys).
304+
305+
### Add the article
306+
307+
To add a new article, you need to create a new markdown file in the `site/pages/en/learn/your-sub-category` directory.
308+
309+
1. Create your new markdown file in the `site/pages/en/learn/your-sub-category` directory.
310+
2. Add the frontmatter to the file.
311+
3. Write your article.
312+
4. Add the navigation entry to `app/site/navigation.json`.
313+
5. Add the translation key to the translation files.
314+
315+
DONE!
316+
317+
### Edit the article
318+
319+
To edit an existing article, you need to find the markdown file in the `site/pages/en/learn/your-sub-category` directory.
320+
321+
> [!NOTE]
322+
> If you rewrite a big part of the article you can add yourself as an author in the frontmatter. **But** if you only fix a typo or a small part of the article, you don't need to add yourself as an author.
323+
324+
### Accessible MDX components
325+
326+
#### Codebox
327+
328+
The codebox component is used to display code snippets. If two code snippets follow without any text between them, they will be displayed in the same codebox, but with two tabs.
329+
330+
```md
331+
'''cjs
332+
const http = require('node:http');
333+
'''
334+
335+
'''mjs
336+
import http from 'node:http';
337+
'''
338+
```
339+
340+
`cjs` and `mjs` are variants of `js`, it's just to display the correct language in the codebox (cjs = CommonJS, mjs = ES Module).

README.md

+2
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,8 @@ These are maintained in different repositories and we urge users to open **issue
105105

106106
[Translation Guidelines][]
107107

108+
[Status Page](https://status.nodejs.org/) of the Node.js web infrastructure.
109+
108110
## Thanks
109111

110112
- Thanks to all contributors and collaborators that make this project possible.

apps/site/.storybook/main.ts

+3-2
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ const config: StorybookConfig = {
3434
webpack: async config => ({
3535
...config,
3636
// We want to conform as much as possible with our target settings
37-
target: 'browserslist',
37+
target: 'browserslist:development',
3838
// Performance Hints do not make sense on Storybook as it is bloated by design
3939
performance: { hints: false },
4040
// `nodevu` is a Node.js-specific package that requires Node.js modules
@@ -52,7 +52,8 @@ const config: StorybookConfig = {
5252
ignoreWarnings: [
5353
e =>
5454
e.message.includes('Critical dep') ||
55-
e.message.includes('was not found in'),
55+
e.message.includes('was not found in') ||
56+
e.message.includes('generated code contains'),
5657
],
5758
}),
5859
};

apps/site/app/[locale]/error.tsx

+14-19
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,26 @@ import { useTranslations } from 'next-intl';
66
import type { FC } from 'react';
77

88
import Button from '@/components/Common/Button';
9-
import GlowingBackdrop from '@/components/Common/GlowingBackdrop';
10-
import CenteredLayout from '@/layouts/Centered';
9+
import GlowingBackdropLayout from '@/layouts/GlowingBackdrop';
1110

1211
const ErrorPage: FC<{ error: Error }> = ({ error }) => {
1312
captureException(error);
1413
const t = useTranslations();
1514

1615
return (
17-
<CenteredLayout>
18-
<GlowingBackdrop />
19-
20-
<main>
21-
500
22-
<h1 className="special -mt-4 text-center">
23-
{t('layouts.error.internalServerError.title')}
24-
</h1>
25-
<p className="-mt-4 max-w-sm text-center text-lg">
26-
{t('layouts.error.internalServerError.description')}
27-
</p>
28-
<Button href="/">
29-
{t('layouts.error.backToHome')}
30-
<ArrowRightIcon />
31-
</Button>
32-
</main>
33-
</CenteredLayout>
16+
<GlowingBackdropLayout>
17+
500
18+
<h1 className="special -mt-4 text-center">
19+
{t('layouts.error.internalServerError.title')}
20+
</h1>
21+
<p className="-mt-4 max-w-sm text-center text-lg">
22+
{t('layouts.error.internalServerError.description')}
23+
</p>
24+
<Button href="/">
25+
{t('layouts.error.backToHome')}
26+
<ArrowRightIcon />
27+
</Button>
28+
</GlowingBackdropLayout>
3429
);
3530
};
3631

apps/site/app/[locale]/not-found.tsx

+23-28
Original file line numberDiff line numberDiff line change
@@ -6,40 +6,35 @@ import { useTranslations } from 'next-intl';
66
import type { FC } from 'react';
77

88
import Button from '@/components/Common/Button';
9-
import GlowingBackdrop from '@/components/Common/GlowingBackdrop';
10-
import CenteredLayout from '@/layouts/Centered';
9+
import GlowingBackdropLayout from '@/layouts/GlowingBackdrop';
1110

1211
const NotFoundPage: FC = () => {
1312
const t = useTranslations();
1413

1514
return (
16-
<CenteredLayout>
17-
<GlowingBackdrop />
18-
19-
<main>
20-
404
21-
<h1 className="special -mt-4 text-center">
22-
{t('layouts.error.notFound.title')}
23-
</h1>
24-
<div className="my-4 flex h-[150px] items-center justify-center md:h-[300px]">
25-
<div className="turtle motion-safe:animate-surf motion-reduce:animate-none">
26-
<Image
27-
src="/static/images/node-mascot.svg"
28-
alt="The Node.js mascot"
29-
height={114.69}
30-
width={100}
31-
/>
32-
</div>
15+
<GlowingBackdropLayout>
16+
404
17+
<h1 className="special -mt-4 text-center">
18+
{t('layouts.error.notFound.title')}
19+
</h1>
20+
<div className="my-4 flex h-[150px] items-center justify-center md:h-[300px]">
21+
<div className="turtle motion-safe:animate-surf motion-reduce:animate-none">
22+
<Image
23+
src="/static/images/node-mascot.svg"
24+
alt="The Node.js mascot"
25+
height={114.69}
26+
width={100}
27+
/>
3328
</div>
34-
<p className="-mt-4 max-w-sm text-center text-lg">
35-
{t('layouts.error.notFound.description')}
36-
</p>
37-
<Button href="/">
38-
{t('layouts.error.backToHome')}
39-
<ArrowRightIcon />
40-
</Button>
41-
</main>
42-
</CenteredLayout>
29+
</div>
30+
<p className="-mt-4 max-w-sm text-center text-lg">
31+
{t('layouts.error.notFound.description')}
32+
</p>
33+
<Button href="/">
34+
{t('layouts.error.backToHome')}
35+
<ArrowRightIcon />
36+
</Button>
37+
</GlowingBackdropLayout>
4338
);
4439
};
4540

apps/site/app/global-error.tsx

+12-19
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,8 @@ import { captureException } from '@sentry/nextjs';
55
import type { FC } from 'react';
66

77
import Button from '@/components/Common/Button';
8-
import GlowingBackdrop from '@/components/Common/GlowingBackdrop';
98
import BaseLayout from '@/layouts/Base';
10-
import CenteredLayout from '@/layouts/Centered';
9+
import GlowingBackdropLayout from '@/layouts/GlowingBackdrop';
1110

1211
const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
1312
captureException(error);
@@ -16,23 +15,17 @@ const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => {
1615
<html>
1716
<body>
1817
<BaseLayout>
19-
<CenteredLayout>
20-
<GlowingBackdrop />
21-
22-
<main>
23-
500
24-
<h1 className="special -mt-4 text-center">
25-
Internal Server Error
26-
</h1>
27-
<p className="-mt-4 max-w-sm text-center text-lg">
28-
This page has thrown a non-recoverable error.
29-
</p>
30-
<Button href="/">
31-
Back to Home
32-
<ArrowRightIcon />
33-
</Button>
34-
</main>
35-
</CenteredLayout>
18+
<GlowingBackdropLayout>
19+
500
20+
<h1 className="special -mt-4 text-center">Internal Server Error</h1>
21+
<p className="-mt-4 max-w-sm text-center text-lg">
22+
This page has thrown a non-recoverable error.
23+
</p>
24+
<Button href="/">
25+
Back to Home
26+
<ArrowRightIcon />
27+
</Button>
28+
</GlowingBackdropLayout>
3629
</BaseLayout>
3730
</body>
3831
</html>

apps/site/components/Common/ActiveLink/__tests__/index.test.mjs

+65
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,15 @@
11
import { render, screen } from '@testing-library/react';
22

3+
import { VERSION_SUPPORT_SHORTCUT } from '@/next.constants.mjs';
4+
35
import ActiveLink from '..';
46

7+
// mock usePathname, but retain all the other imports
8+
jest.mock('@/navigation.mjs', () => ({
9+
...jest.requireActual('@/navigation.mjs'),
10+
usePathname: jest.fn(),
11+
}));
12+
513
describe('ActiveLink', () => {
614
it('renders as localized link', () => {
715
render(
@@ -38,4 +46,61 @@ describe('ActiveLink', () => {
3846
'link active'
3947
);
4048
});
49+
50+
it('does not set active class when href base does not match', () => {
51+
const { usePathname } = require('@/navigation.mjs');
52+
usePathname.mockReturnValue('/not-link/sublink');
53+
54+
render(
55+
<ActiveLink
56+
className="link"
57+
activeClassName="active"
58+
allowSubPath={true}
59+
href={'/link/sub-link'}
60+
>
61+
Link
62+
</ActiveLink>
63+
);
64+
65+
expect(screen.findByText('Link')).resolves.toHaveAttribute('class', 'link');
66+
});
67+
68+
it('sets active class when href is other than VERSION_SUPPORT_SHORTCUT', () => {
69+
const { usePathname } = require('@/navigation.mjs');
70+
usePathname.mockReturnValue('/link/sublink');
71+
72+
render(
73+
<ActiveLink
74+
className="link"
75+
activeClassName="active"
76+
allowSubPath={true}
77+
href={'/link/sub-link'}
78+
>
79+
Link
80+
</ActiveLink>
81+
);
82+
83+
expect(screen.findByText('Link')).resolves.toHaveAttribute(
84+
'class',
85+
'link active'
86+
);
87+
});
88+
89+
it('does not set active class when href is VERSION_SUPPORT_SHORTCUT', () => {
90+
const { usePathname } = require('@/navigation.mjs');
91+
usePathname.mockReturnValue(VERSION_SUPPORT_SHORTCUT);
92+
93+
render(
94+
<ActiveLink
95+
className="link"
96+
activeClassName="active"
97+
allowSubPath={true}
98+
href={VERSION_SUPPORT_SHORTCUT}
99+
>
100+
Link
101+
</ActiveLink>
102+
);
103+
104+
expect(screen.findByText('Link')).resolves.toHaveAttribute('class', 'link');
105+
});
41106
});

0 commit comments

Comments
 (0)