The Node.js® Website

feat: introduced base website redesign layouts (#6145)

* refactor: updated components to be functional for website redesign

* chore: hooks separate generic hooks

* chore: updated storybook previews for redesign

* chore: removed other languages as they will be translated on crowdin

* fix: updated base styles for redesign

* chore: updated types

* feat: added new layouts (base, and article layout) and related "providers"

* feat: updated mdx engine and shared context and app layouts

* meta: updated packages, navigation, tailwind config, etc

* chore: moved package to prod deps

* fix: mocked module

* chore: design fixes

* fix: last story fix

* meta: mismatch of lock file

* fix: fixed styles and minor content-wise bug fixes

* fix: home icon go home

* chore: home aria label

* chore: some minimum design fixes

* refactor: paddings merged

* refactor: footer top border added

* fix: contrast ratio on dark mode breadcrumb

* fix: colspan changed to 2 for missing border

* fix: old layout table heading

* refactor: gradient and shadow colors replaced with theme colors

* chore: moved the `with` components to `components`

* refactor: tw config alpha channel and xl content padding

---------

Co-authored-by: Caner Akdas <canerakdas@gmail.com>

authored by

Claudio W
Caner Akdas
and committed by
GitHub
5e4852ee ff32553d

+1316 -3753
-21
.storybook/constants.ts
··· 1 - import { Open_Sans, IBM_Plex_Mono } from 'next/font/google'; 2 - 3 1 // This defines "execution" modes that Chromatic will run on the each Storybook Story 4 2 // This allows us to test each Story with different parameters 5 3 // @see https://www.chromatic.com/blog/introducing-story-modes/ ··· 28 26 small: { name: 'Small', styles: { width: '414px', height: '896px' } }, 29 27 large: { name: 'Large', styles: { width: '1024px', height: '768px' } }, 30 28 }; 31 - 32 - // This configures the Next.js Font for Open Sans 33 - // We then export a variable and class name to be used 34 - // within Tailwind (tailwind.config.ts) and Storybook (preview.js) 35 - export const OPEN_SANS_FONT = Open_Sans({ 36 - weight: ['300', '400', '600', '700'], 37 - display: 'fallback', 38 - subsets: ['latin'], 39 - variable: '--font-open-sans', 40 - }); 41 - 42 - // This configures the Next.js Font for IBM Plex Mono 43 - // We then export a variable and class name to be used 44 - // within Tailwind (tailwind.config.ts) and Storybook (preview.js) 45 - export const IBM_PLEX_MONO_FONT = IBM_Plex_Mono({ 46 - weight: ['600'], 47 - subsets: ['latin'], 48 - variable: '--font-ibm-plex-mono', 49 - });
+1 -6
.storybook/main.ts
··· 5 5 // note: this is hard-coded sadly as next/font can only be loaded within next.js context 6 6 '__variable_open-sans-normal', 7 7 // note: this is hard-coded sadly as next/font can only be loaded within next.js context 8 - '__variable_ibm-plex-mono-normal-600', 9 - 'font-open-sans', 10 - 'bg-white', 11 - 'text-neutral-950', 12 - 'dark:bg-neutral-950', 13 - 'dark:text-white' 8 + '__variable_ibm-plex-mono-normal-600' 14 9 ); 15 10 16 11 const config: StorybookConfig = {
+1
.storybook/preview.tsx
··· 7 7 8 8 import englishLocale from '@/i18n/locales/en.json'; 9 9 10 + import '../next.fonts'; 10 11 import '../styles/new/index.css'; 11 12 12 13 const preview: Preview = {
+15 -3
app/[locale]/[[...path]]/page.tsx
··· 95 95 if (source.length && filename.length) { 96 96 // This parses the source Markdown content and returns a React Component and 97 97 // relevant context from the Markdown File 98 - const { MDXContent, frontmatter, headings } = 98 + const { MDXContent, frontmatter, headings, readingTime } = 99 99 await dynamicRouter.getMDXContent(source, filename); 100 100 101 + // Metadata and shared Context to be available through the lifecycle of the page 102 + const sharedContext = { 103 + frontmatter, 104 + headings, 105 + pathname: `/${pathname}`, 106 + readingTime, 107 + filename, 108 + }; 109 + 101 110 // Defines a shared Server Context for the Client-Side 102 111 // That is shared for all pages under the dynamic router 103 - setClientContext({ frontmatter, headings, pathname }); 112 + setClientContext(sharedContext); 104 113 114 + // The Matter Provider allows Client-Side injection of the data 115 + // to a shared React Client Provider even though the page is rendered 116 + // within a server-side context 105 117 return ( 106 - <MatterProvider matter={frontmatter} headings={headings}> 118 + <MatterProvider {...sharedContext}> 107 119 <WithLayout layout={frontmatter.layout}> 108 120 <MDXRenderer Component={MDXContent} /> 109 121 </WithLayout>
+20 -10
app/[locale]/layout.tsx
··· 1 1 import { Analytics } from '@vercel/analytics/react'; 2 - import { Source_Sans_3 } from 'next/font/google'; 2 + import classNames from 'classnames'; 3 3 import { getLocale } from 'next-intl/server'; 4 4 import type { FC, PropsWithChildren } from 'react'; 5 5 6 - import BaseLayout from '@/layouts/BaseLayout'; 7 - import { VERCEL_ENV } from '@/next.constants.mjs'; 6 + import LegacyBaseLayout from '@/layouts/BaseLayout'; 7 + import NewBaseLayout from '@/layouts/New/Base'; 8 + import { ENABLE_WEBSITE_REDESIGN, VERCEL_ENV } from '@/next.constants.mjs'; 9 + import { IBM_PLEX_MONO, OPEN_SANS, SOURCE_SANS } from '@/next.fonts'; 8 10 import { availableLocalesMap, defaultLocale } from '@/next.locales.mjs'; 9 11 import { LocaleProvider } from '@/providers/localeProvider'; 10 12 import { ThemeProvider } from '@/providers/themeProvider'; 11 13 12 - import '@/styles/old/index.css'; 14 + // Uses a WebPack/TurboPack Alias for resolving Global Styles 15 + // @deprecated remove when website redesign is done 16 + // eslint-disable-next-line import/no-unresolved 17 + import 'globalStyles'; 13 18 14 - const sourceSans = Source_Sans_3({ 15 - weight: ['400', '600'], 16 - display: 'fallback', 17 - subsets: ['latin'], 19 + // Defines the App Fonts based on being on Website Redesign or not 20 + // @deprecated remove when website redesign is done 21 + const fontClasses = classNames(IBM_PLEX_MONO.variable, { 22 + [SOURCE_SANS.className]: !ENABLE_WEBSITE_REDESIGN, 23 + [OPEN_SANS.variable]: ENABLE_WEBSITE_REDESIGN, 18 24 }); 19 25 26 + // Defines the Base Layout based on being on Website Redesign or not 27 + // @deprecated remove when website redesign is done 28 + const AppLayout = ENABLE_WEBSITE_REDESIGN ? NewBaseLayout : LegacyBaseLayout; 29 + 20 30 const RootLayout: FC<PropsWithChildren> = async ({ children }) => { 21 31 const locale = await getLocale(); 22 32 23 33 const { langDir, hrefLang } = availableLocalesMap[locale] || defaultLocale; 24 34 25 35 return ( 26 - <html className={sourceSans.className} dir={langDir} lang={hrefLang}> 36 + <html className={fontClasses} dir={langDir} lang={hrefLang}> 27 37 <body suppressHydrationWarning> 28 38 <LocaleProvider> 29 39 <ThemeProvider> 30 - <BaseLayout>{children}</BaseLayout> 40 + <AppLayout>{children}</AppLayout> 31 41 </ThemeProvider> 32 42 </LocaleProvider> 33 43
+4
client-context.ts
··· 10 10 frontmatter: {}, 11 11 pathname: '', 12 12 headings: [], 13 + readingTime: { text: '', minutes: 0, time: 0, words: 0 }, 14 + filename: '', 13 15 }; 14 16 15 17 return serverSharedContext; ··· 21 23 getClientContext().frontmatter = data.frontmatter; 22 24 getClientContext().pathname = data.pathname; 23 25 getClientContext().headings = data.headings; 26 + getClientContext().readingTime = data.readingTime; 27 + getClientContext().filename = data.filename; 24 28 };
+2 -1
components/Common/Breadcrumbs/BreadcrumbLink/index.module.css
··· 5 5 px-2 6 6 py-1 7 7 font-semibold 8 - text-white; 8 + text-white 9 + dark:text-white; 9 10 10 11 &:hover { 11 12 @apply bg-green-700
+3 -2
components/Common/Breadcrumbs/index.tsx
··· 6 6 import BreadcrumbLink from '@/components/Common/Breadcrumbs/BreadcrumbLink'; 7 7 import BreadcrumbRoot from '@/components/Common/Breadcrumbs/BreadcrumbRoot'; 8 8 import BreadcrumbTruncatedItem from '@/components/Common/Breadcrumbs/BreadcrumbTruncatedItem'; 9 + import type { FormattedMessage } from '@/types'; 9 10 10 11 type BreadcrumbLink = { 11 - label: string; 12 + label: FormattedMessage; 12 13 href: LinkProps['href']; 13 14 }; 14 15 ··· 38 39 39 40 return ( 40 41 <BreadcrumbItem 41 - key={link.href.toString()} 42 + key={link.label.toString()} 42 43 hidden={hidden} 43 44 hideSeparator={isLastItem} 44 45 position={position + +!hideHome}
+12 -4
components/Common/MetaBar/index.module.css
··· 1 1 .wrapper { 2 2 @apply flex 3 - w-80 4 3 flex-col 5 4 items-start 6 5 gap-8 7 6 border-l 8 - border-neutral-200 9 - p-6 10 - dark:border-neutral-900; 7 + border-l-neutral-200 8 + px-4 9 + py-6 10 + dark:border-l-neutral-900 11 + md:max-w-xs 12 + lg:px-6 13 + xs:mt-8 14 + xs:w-full 15 + xs:border-l-0 16 + xs:border-t 17 + xs:border-t-neutral-200 18 + xs:dark:border-t-neutral-900; 11 19 12 20 dt { 13 21 @apply mb-2
+8 -9
components/Common/MetaBar/index.tsx
··· 11 11 items: Record<string, React.ReactNode>; 12 12 headings?: { 13 13 items: Heading[]; 14 - depth?: number; 14 + minDepth?: number; 15 15 }; 16 16 }; 17 17 ··· 19 19 const t = useTranslations(); 20 20 21 21 // The default depth of headings to display in the table of contents. 22 - const { depth = 2, items: headingItems = [] } = headings || {}; 22 + const { minDepth = 2, items: headingItems = [] } = headings || {}; 23 23 24 24 const heading = useMemo( 25 - () => headingItems.filter(head => head.depth === depth), 26 - [depth, headingItems] 25 + () => headingItems.filter(({ depth }) => depth >= minDepth && depth <= 4), 26 + [minDepth, headingItems] 27 27 ); 28 28 29 29 return ( ··· 35 35 <dd>{value}</dd> 36 36 </Fragment> 37 37 ))} 38 + 38 39 {heading.length > 0 && ( 39 - <Fragment key="tableOfContents"> 40 + <> 40 41 <dt>{t('components.metabar.tableOfContents')}</dt> 41 42 <dd> 42 43 <ol> 43 44 {heading.map(head => ( 44 45 <li key={head.value}> 45 - <Link href={`#${head?.data?.id || head.value}`}> 46 - {head.value} 47 - </Link> 46 + <Link href={`#${head?.data?.id}`}>{head.value}</Link> 48 47 </li> 49 48 ))} 50 49 </ol> 51 50 </dd> 52 - </Fragment> 51 + </> 53 52 )} 54 53 </dl> 55 54 </div>
+7 -2
components/Common/Select/index.module.css
··· 5 5 gap-1.5; 6 6 7 7 .label { 8 - @apply text-sm 8 + @apply block 9 + w-full 10 + text-sm 9 11 font-medium 10 12 text-neutral-800 11 13 dark:text-neutral-200; ··· 13 15 14 16 .trigger { 15 17 @apply inline-flex 18 + h-11 19 + w-full 16 20 min-w-[17rem] 17 21 items-center 18 22 justify-between ··· 97 101 98 102 .inline { 99 103 .trigger { 100 - @apply min-w-fit 104 + @apply h-auto 105 + min-w-fit 101 106 px-2.5 102 107 py-2 103 108 text-sm
+53 -45
components/Common/Select/index.stories.tsx
··· 27 27 args: { 28 28 values: [ 29 29 { 30 - value: 'section-1', 31 30 label: 'Getting Started', 32 - }, 33 - { 34 - value: 'section-2', 35 - label: 'How to install Node.js', 36 - }, 37 - { 38 - value: 'section-3', 39 - label: 'How much JavaScript do you need to know to use Node.js?', 40 - }, 41 - { 42 - value: 'section-4', 43 - label: 'Differences between Node.js and the Browser', 44 - }, 45 - { 46 - value: 'section-5', 47 - label: 'The V8 JavaScript Engine', 48 - }, 49 - { 50 - value: 'section-6', 51 - label: 'An introduction to the NPM package manager', 52 - }, 53 - { 54 - value: 'section-7', 55 - label: 'ECMAScript 2015 (ES6) and beyond', 56 - }, 57 - { 58 - value: 'section-8', 59 - label: 'Node.js, the difference between development and production', 31 + items: [ 32 + { 33 + value: 'section-1', 34 + label: 'Getting Started', 35 + }, 36 + { 37 + value: 'section-2', 38 + label: 'How to install Node.js', 39 + }, 40 + { 41 + value: 'section-3', 42 + label: 'How much JavaScript do you need to know to use Node.js?', 43 + }, 44 + { 45 + value: 'section-4', 46 + label: 'Differences between Node.js and the Browser', 47 + }, 48 + { 49 + value: 'section-5', 50 + label: 'The V8 JavaScript Engine', 51 + }, 52 + { 53 + value: 'section-6', 54 + label: 'An introduction to the NPM package manager', 55 + }, 56 + { 57 + value: 'section-7', 58 + label: 'ECMAScript 2015 (ES6) and beyond', 59 + }, 60 + { 61 + value: 'section-8', 62 + label: 'Node.js, the difference between development and production', 63 + }, 64 + ], 60 65 }, 61 66 ], 62 - label: 'Getting Started', 63 - dropdownLabel: 'Getting Started', 64 67 placeholder: 'Select a guide', 68 + label: 'Getting Started', 65 69 }, 66 70 }; 67 71 ··· 69 73 args: { 70 74 values: [ 71 75 { 72 - value: 'linux', 73 - label: 'Linux', 74 - iconImage: <Linux width={16} height={16} />, 75 - }, 76 - { 77 - value: 'macos', 78 - label: 'MacOS', 79 - iconImage: <Apple width={16} height={16} />, 80 - }, 81 - { 82 - value: 'windows', 83 - label: 'Windows', 84 - iconImage: <Microsoft width={16} height={16} />, 76 + label: 'Platform', 77 + items: [ 78 + { 79 + value: 'linux', 80 + label: 'Linux', 81 + iconImage: <Linux width={16} height={16} />, 82 + }, 83 + { 84 + value: 'macos', 85 + label: 'MacOS', 86 + iconImage: <Apple width={16} height={16} />, 87 + }, 88 + { 89 + value: 'windows', 90 + label: 'Windows', 91 + iconImage: <Microsoft width={16} height={16} />, 92 + }, 93 + ], 85 94 }, 86 95 ], 87 - dropdownLabel: 'Platform', 88 96 defaultValue: 'macos', 89 97 inline: true, 90 98 },
+52 -30
components/Common/Select/index.tsx
··· 1 + 'use client'; 2 + 1 3 import { ChevronDownIcon } from '@heroicons/react/24/outline'; 2 4 import * as Primitive from '@radix-ui/react-select'; 3 5 import classNames from 'classnames'; 4 6 import { useId, useMemo } from 'react'; 5 7 import type { FC } from 'react'; 6 8 9 + import type { FormattedMessage } from '@/types'; 10 + 7 11 import styles from './index.module.css'; 8 12 9 13 type SelectValue = { 10 - label: string; 14 + label: FormattedMessage; 11 15 value: string; 12 16 iconImage?: React.ReactNode; 13 17 }; 14 18 19 + type SelectGroup = { 20 + label?: FormattedMessage; 21 + items: SelectValue[]; 22 + }; 23 + 24 + const isStringArray = (values: unknown[]): values is string[] => 25 + Boolean(values[0] && typeof values[0] === 'string'); 26 + 27 + const isValuesArray = (values: unknown[]): values is SelectValue[] => 28 + Boolean(values[0] && typeof values[0] === 'object' && 'value' in values[0]); 29 + 15 30 type SelectProps = { 16 - values: SelectValue[] | string[]; 31 + values: SelectGroup[] | SelectValue[] | string[]; 17 32 defaultValue?: string; 18 33 placeholder?: string; 19 - dropdownLabel?: string; 20 34 label?: string; 21 35 inline?: boolean; 22 36 onChange?: (value: string) => void; ··· 27 41 defaultValue, 28 42 placeholder, 29 43 label, 30 - dropdownLabel, 31 44 inline, 32 45 onChange, 33 46 }) => { 34 47 const id = useId(); 48 + 35 49 const mappedValues = useMemo(() => { 36 - const [firstItem] = values; 50 + let mappedValues = values; 37 51 38 - const items = 39 - typeof firstItem === 'string' 40 - ? values.map(value => ({ value, label: value })) 41 - : values; 52 + if (isStringArray(mappedValues)) { 53 + mappedValues = mappedValues.map(value => ({ label: value, value })); 54 + } 42 55 43 - return items as SelectValue[]; 56 + if (isValuesArray(mappedValues)) { 57 + return [{ items: mappedValues }]; 58 + } 59 + 60 + return mappedValues; 44 61 }, [values]); 45 62 46 63 return ( ··· 50 67 {label} 51 68 </label> 52 69 )} 53 - <Primitive.Root defaultValue={defaultValue} onValueChange={onChange}> 70 + <Primitive.Root value={defaultValue} onValueChange={onChange}> 54 71 <Primitive.Trigger 55 72 className={styles.trigger} 56 - aria-label={label || dropdownLabel} 73 + aria-label={label} 57 74 id={id} 58 75 > 59 76 <Primitive.Value placeholder={placeholder} /> ··· 65 82 className={classNames(styles.dropdown, { [styles.inline]: inline })} 66 83 > 67 84 <Primitive.Viewport> 68 - <Primitive.Group> 69 - {dropdownLabel && ( 70 - <Primitive.Label className={`${styles.item} ${styles.label}`}> 71 - {dropdownLabel} 72 - </Primitive.Label> 73 - )} 74 - {mappedValues.map(({ value, label, iconImage }) => ( 75 - <Primitive.Item 76 - key={value} 77 - value={value} 78 - className={`${styles.item} ${styles.text}`} 79 - > 80 - <Primitive.ItemText> 81 - {iconImage} 85 + {mappedValues.map(({ label, items }, key) => ( 86 + <Primitive.Group key={label?.toString() || key}> 87 + {label && ( 88 + <Primitive.Label 89 + className={classNames(styles.item, styles.label)} 90 + > 82 91 {label} 83 - </Primitive.ItemText> 84 - </Primitive.Item> 85 - ))} 86 - </Primitive.Group> 92 + </Primitive.Label> 93 + )} 94 + 95 + {items.map(({ value, label, iconImage }) => ( 96 + <Primitive.Item 97 + key={value} 98 + value={value} 99 + className={classNames(styles.item, styles.text)} 100 + > 101 + <Primitive.ItemText> 102 + {iconImage} 103 + {label} 104 + </Primitive.ItemText> 105 + </Primitive.Item> 106 + ))} 107 + </Primitive.Group> 108 + ))} 87 109 </Primitive.Viewport> 88 110 </Primitive.Content> 89 111 </Primitive.Portal>
+1
components/Common/Sidebar/SidebarGroup/index.module.css
··· 15 15 16 16 .itemList { 17 17 @apply m-0 18 + mt-1 18 19 flex 19 20 flex-col 20 21 items-start
+4 -15
components/Common/Sidebar/SidebarGroup/index.tsx
··· 1 1 import type { ComponentProps, FC } from 'react'; 2 2 3 3 import SidebarItem from '@/components/Common/Sidebar/SidebarItem'; 4 + import type { FormattedMessage } from '@/types'; 4 5 5 6 import styles from './index.module.css'; 6 7 7 8 type SidebarGroupProps = { 8 - groupName: string; 9 + groupName: FormattedMessage; 9 10 items: ComponentProps<typeof SidebarItem>[]; 10 - activeItem?: ComponentProps<typeof SidebarItem>; 11 11 }; 12 12 13 - const SidebarGroup: FC<SidebarGroupProps> = ({ 14 - groupName, 15 - items, 16 - activeItem, 17 - }) => ( 13 + const SidebarGroup: FC<SidebarGroupProps> = ({ groupName, items }) => ( 18 14 <section className={styles.group}> 19 15 <label className={styles.groupName}>{groupName}</label> 20 16 <ul className={styles.itemList}> 21 17 {items.map(({ title, url }) => ( 22 - <SidebarItem 23 - key={title} 24 - title={title} 25 - url={url} 26 - isActive={ 27 - activeItem?.title === title && activeItem.url === activeItem.url 28 - } 29 - /> 18 + <SidebarItem key={url} title={title} url={url} /> 30 19 ))} 31 20 </ul> 32 21 </section>
+6 -10
components/Common/Sidebar/SidebarItem/index.module.css
··· 1 1 .sideBarItem { 2 2 @apply flex 3 3 w-full 4 - list-none; 4 + list-none 5 + text-neutral-800 6 + dark:text-neutral-200; 5 7 6 8 a { 7 9 @apply w-full 8 10 p-2 9 11 text-sm 10 - font-regular 11 - text-neutral-800 12 - dark:text-neutral-200; 12 + font-regular; 13 13 } 14 14 } 15 15 16 16 .active { 17 17 @apply rounded 18 - bg-green-600; 19 - 20 - a, 21 - a:hover { 22 - @apply text-white 18 + bg-green-600 19 + text-white 23 20 dark:text-white; 24 - } 25 21 }
+8 -15
components/Common/Sidebar/SidebarItem/index.tsx
··· 1 - import classNames from 'classnames'; 2 1 import type { FC } from 'react'; 3 2 4 - import Link from '@/components/Link'; 3 + import ActiveLink from '@/components/Common/ActiveLink'; 4 + import type { FormattedMessage } from '@/types'; 5 5 6 6 import styles from './index.module.css'; 7 7 8 8 type SidebarItemProps = { 9 - title: string; 9 + title: FormattedMessage; 10 10 url: string; 11 - isActive?: boolean; 12 11 }; 13 12 14 - const SidebarItem: FC<SidebarItemProps> = ({ 15 - url, 16 - title, 17 - isActive = false, 18 - }) => ( 19 - <li 20 - className={classNames(styles.sideBarItem, { 21 - [styles.active]: isActive, 22 - })} 23 - > 24 - <Link href={url}>{title}</Link> 13 + const SidebarItem: FC<SidebarItemProps> = ({ url, title }) => ( 14 + <li className={styles.sideBarItem}> 15 + <ActiveLink href={url} activeClassName={styles.active}> 16 + {title} 17 + </ActiveLink> 25 18 </li> 26 19 ); 27 20
+14 -1
components/Common/Sidebar/index.module.css
··· 11 11 py-6 12 12 dark:border-r-neutral-900 13 13 dark:bg-neutral-950 14 - md:max-w-xs; 14 + md:max-w-xs 15 + lg:px-6 16 + xs:w-full 17 + xs:border-r-0; 18 + 19 + > section { 20 + @apply block 21 + xs:hidden; 22 + } 23 + 24 + > div { 25 + @apply w-full 26 + sm:hidden; 27 + } 15 28 }
-78
components/Common/Sidebar/index.stories.tsx
··· 79 79 }, 80 80 }; 81 81 82 - export const ActiveItem: Story = { 83 - args: { 84 - groups: [ 85 - { 86 - groupName: 'About Node.js', 87 - items: [ 88 - { 89 - url: '/item1', 90 - title: 'About Node.js', 91 - }, 92 - { 93 - url: '/item2', 94 - title: 'Project Governance', 95 - }, 96 - { 97 - url: '/item3', 98 - title: 'Releases', 99 - }, 100 - { 101 - url: '/item4', 102 - title: 'Branding', 103 - }, 104 - { 105 - url: '/item5', 106 - title: 'Privacy Policy', 107 - }, 108 - { 109 - url: '/item6', 110 - title: 'Security Reporting', 111 - }, 112 - ], 113 - }, 114 - { 115 - groupName: 'Get Involved', 116 - items: [ 117 - { 118 - url: '/item7', 119 - title: 'Get Involved', 120 - }, 121 - { 122 - url: '/item8', 123 - title: 'Collab Summit', 124 - }, 125 - { 126 - url: '/item9', 127 - title: 'Contribute', 128 - }, 129 - { 130 - url: '/item10', 131 - title: 'Code of Conduct', 132 - }, 133 - ], 134 - }, 135 - { 136 - groupName: 'Download', 137 - items: [ 138 - { 139 - url: '/item11', 140 - title: 'Download', 141 - }, 142 - { 143 - url: '/item12', 144 - title: 'Package Manager', 145 - }, 146 - { 147 - url: '/item13', 148 - title: 'Previous Releases', 149 - }, 150 - ], 151 - }, 152 - ], 153 - activeItem: { 154 - url: '/item1', 155 - title: 'About Node.js', 156 - }, 157 - }, 158 - }; 159 - 160 82 export default { component: Sidebar } as Meta;
+39 -13
components/Common/Sidebar/index.tsx
··· 1 + 'use client'; 2 + 3 + import { useTranslations } from 'next-intl'; 1 4 import type { ComponentProps, FC } from 'react'; 2 5 6 + import Select from '@/components/Common/Select'; 3 7 import SidebarGroup from '@/components/Common/Sidebar/SidebarGroup'; 4 - import type SidebarItem from '@/components/Common/Sidebar/SidebarItem'; 8 + import { useClientContext } from '@/hooks'; 9 + import { useRouter } from '@/navigation.mjs'; 5 10 6 11 import styles from './index.module.css'; 7 12 8 13 type SidebarProps = { 9 14 groups: ComponentProps<typeof SidebarGroup>[]; 10 - activeItem?: ComponentProps<typeof SidebarItem>; 11 15 }; 12 16 13 - const SideBar: FC<SidebarProps> = ({ groups, activeItem }) => ( 14 - <aside className={styles.sideBar}> 15 - {groups.map(({ groupName, items }) => ( 16 - <SidebarGroup 17 - key={groupName} 18 - groupName={groupName} 19 - items={items} 20 - activeItem={activeItem} 17 + const SideBar: FC<SidebarProps> = ({ groups }) => { 18 + const t = useTranslations(); 19 + const { pathname } = useClientContext(); 20 + const { push } = useRouter(); 21 + 22 + const selectItems = groups.map(({ items, groupName }) => ({ 23 + label: groupName, 24 + items: items.map(item => ({ value: item.url, label: item.title })), 25 + })); 26 + 27 + const currentItem = selectItems 28 + .map(item => item.items) 29 + .flat() 30 + .find(item => pathname === item.value); 31 + 32 + return ( 33 + <aside className={styles.sideBar}> 34 + {groups.map(({ groupName, items }) => ( 35 + <SidebarGroup 36 + key={groupName.toString()} 37 + groupName={groupName} 38 + items={items} 39 + /> 40 + ))} 41 + 42 + <Select 43 + label={t('components.common.sidebar.title')} 44 + values={selectItems} 45 + defaultValue={currentItem?.value} 46 + onChange={value => push(value)} 21 47 /> 22 - ))} 23 - </aside> 24 - ); 48 + </aside> 49 + ); 50 + }; 25 51 26 52 export default SideBar;
+3
components/Containers/Footer/index.module.css
··· 3 3 flex-col 4 4 items-center 5 5 gap-6 6 + border-t 7 + border-neutral-200 6 8 px-8 7 9 py-4 10 + dark:border-neutral-900 8 11 md:flex-row 9 12 md:justify-between 10 13 md:py-5;
+1 -1
components/Containers/Footer/index.tsx
··· 1 1 import { useTranslations } from 'next-intl'; 2 2 import type { FC, SVGProps } from 'react'; 3 3 4 - import NavItem from '@/components/Containers/NavItem'; 4 + import NavItem from '@/components/Common/NavItem'; 5 5 import GitHub from '@/components/Icons/Social/GitHub'; 6 6 import LinkedIn from '@/components/Icons/Social/LinkedIn'; 7 7 import Mastodon from '@/components/Icons/Social/Mastodon';
components/Containers/NavItem/index.module.css components/Common/NavItem/index.module.css
+1 -1
components/Containers/NavItem/index.stories.tsx components/Common/NavItem/index.stories.tsx
··· 1 1 import type { Meta as MetaObj, StoryObj } from '@storybook/react'; 2 2 3 - import NavItem from '@/components/Containers/NavItem'; 3 + import NavItem from '@/components/Common/NavItem'; 4 4 5 5 type Story = StoryObj<typeof NavItem>; 6 6 type Meta = MetaObj<typeof NavItem>;
+1
components/Containers/NavItem/index.tsx components/Common/NavItem/index.tsx
··· 31 31 href={href} 32 32 className={classNames(styles.navItem, styles[type], className)} 33 33 activeClassName={styles.active} 34 + allowSubPath 34 35 > 35 36 <span className={styles.label}>{children}</span> 36 37 {showIcon && <ArrowUpRightIcon className={styles.icon} />}
components/Containers/NavigationBar/index.module.css components/Containers/NavBar/index.module.css
+10 -10
components/Containers/NavigationBar/index.stories.tsx components/Containers/NavBar/index.stories.tsx
··· 1 1 import type { Meta as MetaObj, StoryObj } from '@storybook/react'; 2 2 3 - import NavigationBar from './index'; 3 + import NavBar from '@/components/Containers/NavBar'; 4 4 5 - type Story = StoryObj<typeof NavigationBar>; 6 - type Meta = MetaObj<typeof NavigationBar>; 5 + type Story = StoryObj<typeof NavBar>; 6 + type Meta = MetaObj<typeof NavBar>; 7 7 8 8 export const Default: Story = { 9 9 args: { 10 10 navItems: [ 11 11 { 12 12 text: 'Learn', 13 - href: '/', 13 + link: '/', 14 14 }, 15 15 { 16 16 text: 'About', 17 - href: '/about', 17 + link: '/about', 18 18 }, 19 19 { 20 20 text: 'Docs', 21 - href: '/docs', 21 + link: '/docs', 22 22 }, 23 23 { 24 24 text: 'Download', 25 - href: '/download', 25 + link: '/download', 26 26 }, 27 27 { 28 28 text: 'Blog', 29 - href: '/blog', 29 + link: '/blog', 30 30 }, 31 31 { 32 32 text: 'Certification', 33 - href: 'https://openjsf.org/certification', 33 + link: 'https://openjsf.org/certification', 34 34 }, 35 35 ], 36 36 languages: { ··· 45 45 }, 46 46 }; 47 47 48 - export default { component: NavigationBar } as Meta; 48 + export default { component: NavBar } as Meta;
+24 -16
components/Containers/NavigationBar/index.tsx components/Containers/NavBar/index.tsx
··· 7 7 import type { FC, ComponentProps } from 'react'; 8 8 9 9 import LanguageDropdown from '@/components/Common/LanguageDropDown'; 10 + import NavItem from '@/components/Common/NavItem'; 10 11 import ThemeToggle from '@/components/Common/ThemeToggle'; 11 - import NavItem from '@/components/Containers/NavItem'; 12 12 import NodejsDark from '@/components/Icons/Logos/NodejsDark'; 13 13 import NodejsLight from '@/components/Icons/Logos/NodejsLight'; 14 14 import GitHub from '@/components/Icons/Social/GitHub'; 15 + import Link from '@/components/Link'; 16 + import type { FormattedMessage } from '@/types'; 15 17 16 18 import style from './index.module.css'; 17 19 18 - type NavItem = { text: string; href: string }; 20 + const navInteractionIcons = { 21 + show: <Hamburger className={style.navInteractionIcon} />, 22 + close: <XMark className={style.navInteractionIcon} />, 23 + }; 19 24 20 25 type NavbarProps = { 21 - navItems: NavItem[]; 26 + navItems: { text: FormattedMessage; link: string }[]; 22 27 languages: ComponentProps<typeof LanguageDropdown>; 23 28 onThemeTogglerClick: () => void; 24 29 }; 25 30 26 - const navInteractionIcons = { 27 - show: <Hamburger className={style.navInteractionIcon} />, 28 - close: <XMark className={style.navInteractionIcon} />, 29 - }; 30 - 31 - const NavigationBar: FC<NavbarProps> = ({ 31 + const NavBar: FC<NavbarProps> = ({ 32 32 navItems, 33 33 languages, 34 34 onThemeTogglerClick, 35 35 }) => { 36 36 const [isMenuOpen, setIsMenuOpen] = useState(false); 37 + 37 38 return ( 38 39 <nav className={`${style.container}`}> 39 40 <div className={style.nodeIconAndMobileItemsToggler}> 40 - <div className={style.nodeIconWrapper}> 41 + <Link className={style.nodeIconWrapper} href="/" aria-label="Home"> 41 42 <NodejsDark className={style.nodejsLogoDark} /> 42 43 <NodejsLight className={style.nodejsLogoLight} /> 43 - </div> 44 + </Link> 45 + 44 46 <Label.Root 45 47 onClick={() => setIsMenuOpen(prev => !prev)} 46 48 className={style.sidebarItemTogglerLabel} ··· 49 51 {navInteractionIcons[isMenuOpen ? 'close' : 'show']} 50 52 </Label.Root> 51 53 </div> 54 + 52 55 <input className="peer hidden" id="sidebarItemToggler" type="checkbox" /> 56 + 53 57 <div className={`${style.main} peer-checked:flex`}> 54 58 <div className={style.navItems}> 55 - {navItems.map(({ text, href }) => ( 56 - <NavItem key={text} href={href}> 59 + {navItems.map(({ text, link }) => ( 60 + <NavItem key={link} href={link}> 57 61 {text} 58 62 </NavItem> 59 63 ))} 60 64 </div> 65 + 61 66 <div className={style.actionsWrapper}> 62 67 <ThemeToggle onClick={onThemeTogglerClick} /> 68 + 63 69 <LanguageDropdown 70 + onChange={languages.onChange} 64 71 availableLanguages={languages.availableLanguages} 65 72 currentLanguage={languages.currentLanguage} 66 73 /> 67 - <a 74 + 75 + <Link 68 76 className={style.ghIconWrapper} 69 77 href="https://github.com/nodejs/node" 70 78 aria-label="Node.js Github" 71 79 > 72 80 <GitHub /> 73 - </a> 81 + </Link> 74 82 </div> 75 83 </div> 76 84 </nav> 77 85 ); 78 86 }; 79 87 80 - export default NavigationBar; 88 + export default NavBar;
+4 -4
components/Downloads/DownloadList.tsx
··· 10 10 11 11 const { getSideNavigation } = useSiteNavigation(); 12 12 13 - const [, ...downloadNavigation] = getSideNavigation('download', { 13 + const [[, downloadNavigationItems]] = getSideNavigation(['download'], { 14 14 shaSums: { nodeVersion: versionWithPrefix }, 15 15 allDownloads: { nodeVersion: versionWithPrefix }, 16 16 }); ··· 18 18 return ( 19 19 <section> 20 20 <ul> 21 - {downloadNavigation.map((item, key) => ( 21 + {downloadNavigationItems.items.map(([key, { label, link }]) => ( 22 22 <li key={key}> 23 - <Link href={item.link}>{item.text}</Link> 24 - {item.key === 'shaSums' && ( 23 + <Link href={link}>{label}</Link> 24 + {key === 'shaSums' && ( 25 25 <a href="https://github.com/nodejs/node#verifying-binaries"> 26 26 {t('components.downloadList.links.shaSums.howToVerify')} 27 27 </a>
+7 -15
components/Downloads/DownloadReleasesTable.tsx
··· 17 17 <table id="tbVersions" className="download-table full-width"> 18 18 <thead> 19 19 <tr> 20 - <td>Version</td> 21 - <td>LTS</td> 22 - <td>Date</td> 23 - <td>V8</td> 24 - <td>npm</td> 25 - <td> 26 - NODE_MODULE_VERSION<a href="#ref-1">[1]</a> 27 - <span id="backref-1"></span> 28 - </td> 29 - <td></td> 20 + <th>Node.js Version</th> 21 + <th>Codename</th> 22 + <th>Release Date</th> 23 + <th colSpan={2}>npm</th> 30 24 </tr> 31 25 </thead> 32 26 <tbody> 33 27 {releaseData.map(release => ( 34 28 <tr key={release.major}> 35 - <td data-label="Version">Node.js {release.version}</td> 36 - <td data-label="LTS">{release.codename}</td> 29 + <td data-label="Version">v{release.version}</td> 30 + <td data-label="LTS">{release.codename || '-'}</td> 37 31 <td data-label="Date"> 38 32 <time>{release.releaseDate}</time> 39 33 </td> 40 - <td data-label="V8">{release.v8}</td> 41 - <td data-label="npm">{release.npm}</td> 42 - <td data-label="NODE_MODULE_VERSION">{release.modules}</td> 34 + <td data-label="npm">v{release.npm}</td> 43 35 <td className="download-table-last"> 44 36 <a 45 37 href={`https://nodejs.org/download/release/${release.versionWithPrefix}/`}
+7 -7
components/SideNavigation.tsx
··· 16 16 }) => { 17 17 const { getSideNavigation } = useSiteNavigation(); 18 18 19 - const sideNavigationItems = getSideNavigation(navigationKey, context); 19 + const [[, sideNavigationItems]] = getSideNavigation([navigationKey], context); 20 20 21 21 return ( 22 22 <nav aria-label="secondary"> 23 23 <ul> 24 - {sideNavigationItems.map(item => ( 25 - <li key={item.key}> 26 - <ActiveLink href={item.link}>{item.text}</ActiveLink> 24 + {sideNavigationItems.items!.map(([key, { link, label, items }]) => ( 25 + <li key={key}> 26 + {link ? <ActiveLink href={link}>{label}</ActiveLink> : label} 27 27 28 - {item.items.length > 0 && ( 28 + {items && items.length > 0 && ( 29 29 <ul> 30 - {item.items.map(({ link, text, key }) => ( 30 + {items.map(([key, { link, label }]) => ( 31 31 <li key={key}> 32 - <ActiveLink href={link}>{text}</ActiveLink> 32 + <ActiveLink href={link}>{label}</ActiveLink> 33 33 </li> 34 34 ))} 35 35 </ul>
+4 -4
components/TopNavigation.tsx
··· 9 9 return ( 10 10 <nav aria-label="primary"> 11 11 <ul className="list-divider-pipe"> 12 - {navigationItems.map(({ link, text }) => ( 13 - <li key={link}> 14 - <ActiveLink href={link} allowSubPath> 15 - {text} 12 + {navigationItems.map(([key, { link, label }]) => ( 13 + <li key={key}> 14 + <ActiveLink href={link!} allowSubPath> 15 + {label} 16 16 </ActiveLink> 17 17 </li> 18 18 ))}
+7
components/__mocks__/github-slugger.mjs
··· 1 + class GitHubSlugger { 2 + slug() { 3 + return 'mock-slug'; 4 + } 5 + } 6 + 7 + export default GitHubSlugger;
+35
components/withBreadcrumbs.tsx
··· 1 + 'use client'; 2 + 3 + import type { FC } from 'react'; 4 + 5 + import Breadcrumbs from '@/components/Common/Breadcrumbs'; 6 + import { useClientContext, useMediaQuery, useSiteNavigation } from '@/hooks'; 7 + import type { NavigationKeys } from '@/types'; 8 + 9 + const WithBreadcrumbs: FC = () => { 10 + const { navigationItems, getSideNavigation } = useSiteNavigation(); 11 + const { pathname } = useClientContext(); 12 + 13 + const isMobileScreen = useMediaQuery('(max-width: 639px)'); 14 + 15 + const getBreadrumbs = () => { 16 + const [navigationKey] = 17 + navigationItems.find(([, item]) => pathname.includes(item.link)) || []; 18 + 19 + if (navigationKey === undefined) { 20 + return []; 21 + } 22 + 23 + return getSideNavigation([navigationKey as NavigationKeys]) 24 + .map(([, item]) => item.items) 25 + .flat() 26 + .filter(([, item]) => pathname.includes(item.link)) 27 + .map(([, item]) => ({ label: item.label, href: item.link })); 28 + }; 29 + 30 + return ( 31 + <Breadcrumbs links={getBreadrumbs()} maxLength={isMobileScreen ? 2 : 4} /> 32 + ); 33 + }; 34 + 35 + export default WithBreadcrumbs;
+7
components/withFooter.tsx
··· 1 + import type { FC } from 'react'; 2 + 3 + import Footer from '@/components/Containers/Footer'; 4 + 5 + const WithFooter: FC = () => <Footer />; 6 + 7 + export default WithFooter;
+41 -22
components/withLayout.tsx
··· 1 - import { useMemo, type FC, type PropsWithChildren } from 'react'; 1 + import type { FC, PropsWithChildren } from 'react'; 2 2 3 - import AboutLayout from '@/layouts/AboutLayout'; 4 - import BlogCategoryLayout from '@/layouts/BlogCategoryLayout'; 5 - import BlogPostLayout from '@/layouts/BlogPostLayout'; 6 - import ContributeLayout from '@/layouts/ContributeLayout'; 7 - import DefaultLayout from '@/layouts/DefaultLayout'; 8 - import DocsLayout from '@/layouts/DocsLayout'; 9 - import DownloadLayout from '@/layouts/DownloadLayout'; 10 - import IndexLayout from '@/layouts/IndexLayout'; 11 - import LearnLayout from '@/layouts/LearnLayout'; 3 + import LegacyAboutLayout from '@/layouts/AboutLayout'; 4 + import LegacyBlogCategoryLayout from '@/layouts/BlogCategoryLayout'; 5 + import LegacyBlogPostLayout from '@/layouts/BlogPostLayout'; 6 + import LegacyContributeLayout from '@/layouts/ContributeLayout'; 7 + import LegacyDefaultLayout from '@/layouts/DefaultLayout'; 8 + import LegacyDocsLayout from '@/layouts/DocsLayout'; 9 + import LegacyDownloadLayout from '@/layouts/DownloadLayout'; 10 + import LegacyIndexLayout from '@/layouts/IndexLayout'; 11 + import LegacyLearnLayout from '@/layouts/LearnLayout'; 12 + import AboutLayout from '@/layouts/New/About'; 13 + import DefaultLayout from '@/layouts/New/Default'; 14 + import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; 12 15 import type { LegacyLayouts } from '@/types'; 13 16 14 - const layoutComponents = { 15 - 'docs.hbs': DocsLayout, 17 + /** @deprecated these should be removed with the website redesin */ 18 + const legacyLayouts = { 19 + 'docs.hbs': LegacyDocsLayout, 20 + 'about.hbs': LegacyAboutLayout, 21 + 'blog-category.hbs': LegacyBlogCategoryLayout, 22 + 'blog-post.hbs': LegacyBlogPostLayout, 23 + 'contribute.hbs': LegacyContributeLayout, 24 + 'download.hbs': LegacyDownloadLayout, 25 + 'index.hbs': LegacyIndexLayout, 26 + 'learn.hbs': LegacyLearnLayout, 27 + 'page.hbs': LegacyDefaultLayout, 28 + } satisfies Record<string, FC>; 29 + 30 + /** all the currently available layouts from website redesign */ 31 + const redesignLayouts = { 32 + 'docs.hbs': DefaultLayout, 16 33 'about.hbs': AboutLayout, 17 - 'blog-category.hbs': BlogCategoryLayout, 18 - 'blog-post.hbs': BlogPostLayout, 19 - 'contribute.hbs': ContributeLayout, 20 - 'download.hbs': DownloadLayout, 21 - 'index.hbs': IndexLayout, 22 - 'learn.hbs': LearnLayout, 34 + 'blog-category.hbs': DefaultLayout, 35 + 'blog-post.hbs': DefaultLayout, 36 + 'contribute.hbs': AboutLayout, 37 + 'download.hbs': DefaultLayout, 38 + 'index.hbs': DefaultLayout, 39 + 'learn.hbs': DefaultLayout, 23 40 'page.hbs': DefaultLayout, 24 41 } satisfies Record<string, FC>; 25 42 43 + /** @deprecated this should be removed once we sunset the legacy layouts */ 44 + const availableLayouts = ENABLE_WEBSITE_REDESIGN 45 + ? redesignLayouts 46 + : legacyLayouts; 47 + 26 48 type WithLayoutProps = PropsWithChildren<{ layout: LegacyLayouts }>; 27 49 28 50 export const WithLayout: FC<WithLayoutProps> = ({ layout, children }) => { 29 - const LayoutComponent = useMemo( 30 - () => layoutComponents[layout] || DefaultLayout, 31 - [layout] 32 - ); 51 + const LayoutComponent = availableLayouts[layout]; 33 52 34 53 return <LayoutComponent>{children}</LayoutComponent>; 35 54 };
+37
components/withMetaBar.tsx
··· 1 + import { useFormatter } from 'next-intl'; 2 + import type { FC } from 'react'; 3 + 4 + import MetaBar from '@/components/Common/MetaBar'; 5 + import GitHub from '@/components/Icons/Social/GitHub'; 6 + import Link from '@/components/Link'; 7 + import { useClientContext } from '@/hooks/server'; 8 + import { getGitHubEditPageUrl } from '@/util/gitHubUtils'; 9 + 10 + const WithMetaBar: FC = () => { 11 + const { headings, readingTime, frontmatter, filename } = useClientContext(); 12 + const formatter = useFormatter(); 13 + 14 + const lastUpdated = formatter.dateTime(frontmatter.date ?? new Date(), { 15 + month: 'short', 16 + day: '2-digit', 17 + year: 'numeric', 18 + }); 19 + 20 + return ( 21 + <MetaBar 22 + items={{ 23 + 'components.metabar.lastUpdated': lastUpdated, 24 + 'components.metabar.readingTime': readingTime.text, 25 + 'components.metabar.contribute': ( 26 + <> 27 + <GitHub className="fill-neutral-700 dark:fill-neutral-100" /> 28 + <Link href={getGitHubEditPageUrl(filename)}>Edit this page</Link> 29 + </> 30 + ), 31 + }} 32 + headings={{ items: headings }} 33 + /> 34 + ); 35 + }; 36 + 37 + export default WithMetaBar;
+39
components/withNavBar.tsx
··· 1 + 'use client'; 2 + 3 + import { useLocale } from 'next-intl'; 4 + import { useTheme } from 'next-themes'; 5 + import type { FC } from 'react'; 6 + 7 + import NavBar from '@/components/Containers/NavBar'; 8 + import { useClientContext, useSiteNavigation } from '@/hooks'; 9 + import { useRouter } from '@/navigation.mjs'; 10 + import { availableLocales } from '@/next.locales.mjs'; 11 + 12 + const WithNavBar: FC = () => { 13 + const { navigationItems } = useSiteNavigation(); 14 + const { resolvedTheme, setTheme } = useTheme(); 15 + const { pathname } = useClientContext(); 16 + const { replace } = useRouter(); 17 + 18 + const locale = useLocale(); 19 + 20 + const toggleCurrnetTheme = () => 21 + setTheme(resolvedTheme === 'dark' ? 'light' : 'dark'); 22 + 23 + return ( 24 + <NavBar 25 + onThemeTogglerClick={toggleCurrnetTheme} 26 + languages={{ 27 + currentLanguage: locale, 28 + availableLanguages: availableLocales, 29 + onChange: locale => replace(pathname!, { locale: locale.code }), 30 + }} 31 + navItems={navigationItems.map(([, { label, link }]) => ({ 32 + link, 33 + text: label, 34 + }))} 35 + /> 36 + ); 37 + }; 38 + 39 + export default WithNavBar;
+26
components/withSideBar.tsx
··· 1 + import type { RichTranslationValues } from 'next-intl'; 2 + import type { FC } from 'react'; 3 + 4 + import SideBar from '@/components/Common/Sidebar'; 5 + import { useSiteNavigation } from '@/hooks/server'; 6 + import type { NavigationKeys } from '@/types'; 7 + 8 + type WithSideBarProps = { 9 + keys: NavigationKeys[]; 10 + context?: Record<string, RichTranslationValues>; 11 + }; 12 + 13 + const WithSideBar: FC<WithSideBarProps> = ({ keys, context }) => { 14 + const { getSideNavigation } = useSiteNavigation(); 15 + 16 + const mappedSidebarItems = getSideNavigation(keys, context).map( 17 + ([, { label, items }]) => ({ 18 + groupName: label, 19 + items: items.map(([, { label, link }]) => ({ title: label, url: link })), 20 + }) 21 + ); 22 + 23 + return <SideBar groups={mappedSidebarItems} />; 24 + }; 25 + 26 + export default WithSideBar;
+1
hooks/index.ts
··· 1 1 export * from './react-client'; 2 + export * from './react-generic';
-1
hooks/react-client/index.ts
··· 3 3 export { default as useMediaQuery } from './useMediaQuery'; 4 4 export { default as useNotification } from './useNotification'; 5 5 export { default as useClientContext } from './useClientContext'; 6 - export { default as useSiteNavigation } from './useSiteNavigation';
+3 -4
hooks/react-client/useClientContext.ts
··· 2 2 3 3 import { useContext } from 'react'; 4 4 5 - import { usePathname } from '@/navigation.mjs'; 6 5 import { MatterContext } from '@/providers/matterProvider'; 7 6 import type { ClientSharedServerContext } from '@/types'; 8 7 9 8 const useClientContext = (): ClientSharedServerContext => { 10 - const { matter: frontmatter, headings } = useContext(MatterContext); 11 - const pathname = usePathname(); 9 + const { frontmatter, pathname, headings, readingTime, filename } = 10 + useContext(MatterContext); 12 11 13 - return { pathname: pathname || '', frontmatter, headings }; 12 + return { pathname, frontmatter, headings, readingTime, filename }; 14 13 }; 15 14 16 15 export default useClientContext;
-7
hooks/react-client/useSiteNavigation.tsx
··· 1 - 'use client'; 2 - 3 - const useSiteNavigation = () => { 4 - throw new Error('Attempted to call useSiteNavigation from RCC'); 5 - }; 6 - 7 - export default useSiteNavigation;
+1
hooks/react-generic/index.ts
··· 1 + export { default as useSiteNavigation } from './useSiteNavigation';
+68
hooks/react-generic/useSiteNavigation.ts
··· 1 + import { useTranslations } from 'next-intl'; 2 + import type { RichTranslationValues } from 'next-intl'; 3 + 4 + import { siteNavigation } from '@/next.json.mjs'; 5 + import type { 6 + FormattedMessage, 7 + NavigationEntry, 8 + NavigationKeys, 9 + } from '@/types'; 10 + 11 + type Context = Record<string, RichTranslationValues>; 12 + type Navigation = Record<string, NavigationEntry>; 13 + 14 + interface MappedNavigationEntry { 15 + items: [string, MappedNavigationEntry][]; 16 + label: FormattedMessage; 17 + link: string; 18 + } 19 + 20 + // Provides Context replacement for variables within the Link. This is also something that is not going 21 + // to happen in the future with `nodejs/nodejs.dev` codebase 22 + const replaceLinkWithContext = ( 23 + link: string, 24 + context?: RichTranslationValues 25 + ) => 26 + Object.entries(context || {}).reduce( 27 + (finalLink, [find, replace]) => 28 + finalLink.replace( 29 + `{${find}}`, 30 + typeof replace === 'string' ? replace : '' 31 + ), 32 + link 33 + ); 34 + 35 + const useSiteNavigation = () => { 36 + const t = useTranslations(); 37 + 38 + const mapNavigationEntries = (entries: Navigation, context: Context = {}) => { 39 + const getFormattedMessage = (label: string, key: string) => 40 + t.rich(label, context[key] || {}); 41 + 42 + return Object.entries(entries).map( 43 + ([key, { label, link, items }]): [string, MappedNavigationEntry] => [ 44 + key, 45 + { 46 + label: label ? getFormattedMessage(label, key) : '', 47 + link: link ? replaceLinkWithContext(link, context[key]) : '', 48 + items: items ? mapNavigationEntries(items, context) : [], 49 + }, 50 + ] 51 + ); 52 + }; 53 + 54 + const getSideNavigation = (keys: NavigationKeys[], context: Context = {}) => { 55 + const navigationEntries: Navigation = keys.reduce( 56 + (acc, key) => ({ ...acc, [key]: siteNavigation.sideNavigation[key] }), 57 + {} 58 + ); 59 + 60 + return mapNavigationEntries(navigationEntries, context); 61 + }; 62 + 63 + const navigationItems = mapNavigationEntries(siteNavigation.topNavigation); 64 + 65 + return { getSideNavigation, navigationItems }; 66 + }; 67 + 68 + export default useSiteNavigation;
-1
hooks/react-server/index.ts
··· 3 3 export { default as useMediaQuery } from './useMediaQuery'; 4 4 export { default as useNotification } from './useNotification'; 5 5 export { default as useClientContext } from './useClientContext'; 6 - export { default as useSiteNavigation } from './useSiteNavigation';
-75
hooks/react-server/useSiteNavigation.tsx
··· 1 - import { useTranslations } from 'next-intl'; 2 - import type { RichTranslationValues } from 'next-intl'; 3 - 4 - import { siteNavigation } from '@/next.json.mjs'; 5 - import type { 6 - MappedNavigationEntry, 7 - NavigationEntry, 8 - NavigationKeys, 9 - } from '@/types'; 10 - 11 - type Context = Record<string, RichTranslationValues>; 12 - type Navigation = Record<string, NavigationEntry>; 13 - 14 - // Provides Context replacement for variables within the Link. This is also something that is not going 15 - // to happen in the future with `nodejs/nodejs.dev` codebase 16 - const replaceLinkWithContext = ( 17 - link: string, 18 - context?: RichTranslationValues 19 - ) => 20 - Object.entries(context || {}).reduce( 21 - (finalLink, [find, replace]) => 22 - finalLink.replace( 23 - `{${find}}`, 24 - typeof replace === 'string' ? replace : '' 25 - ), 26 - link 27 - ); 28 - 29 - const useSiteNavigation = () => { 30 - const t = useTranslations(); 31 - 32 - const mapNavigationEntries = ( 33 - entries: Navigation, 34 - context: Context = {}, 35 - level = 0, 36 - includeItems = true 37 - ): MappedNavigationEntry[] => { 38 - const getFormattedMessage = (translationId: string, key: string) => 39 - t.rich(translationId, context[key] || {}); 40 - 41 - return Object.entries(entries).map( 42 - ([key, { translationId, link, items }]) => { 43 - const mappedEntry: MappedNavigationEntry = { 44 - text: getFormattedMessage(translationId, key), 45 - link: replaceLinkWithContext(link, context[key]), 46 - items: [], 47 - level, 48 - key, 49 - }; 50 - 51 - if (includeItems && items) { 52 - mappedEntry.items = mapNavigationEntries(items, context, level + 1); 53 - } 54 - 55 - return mappedEntry; 56 - } 57 - ); 58 - }; 59 - 60 - const getSideNavigation = (section: NavigationKeys, context?: Context) => { 61 - const { items, translationId, link } = siteNavigation[section]; 62 - 63 - return mapNavigationEntries( 64 - { [section]: { translationId, link }, ...items }, 65 - context 66 - ); 67 - }; 68 - 69 - return { 70 - getSideNavigation, 71 - navigationItems: mapNavigationEntries(siteNavigation, {}, 0, false), 72 - }; 73 - }; 74 - 75 - export default useSiteNavigation;
+1
hooks/server.ts
··· 1 1 export * from './react-server'; 2 + export * from './react-generic';
-199
i18n/locales/ar.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/de.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
+35 -21
i18n/locales/en.json
··· 18 18 "download": "Download", 19 19 "docs": "Docs", 20 20 "getInvolved": "Get Involved", 21 + "learn": "Learn", 21 22 "security": "Security", 22 23 "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 24 + "blog": "News" 25 + }, 26 + "buttons": { 27 + "toggleLanguage": "Toggle Language", 28 + "toggleTheme": "Toggle dark/light mode" 29 + } 30 + }, 31 + "navigation": { 32 + "learn": { 33 + "gettingStarted": { 34 + "links": { 35 + "gettingStarted": "Getting Started", 28 36 "introductionToNodejs": "Introduction to Node.js", 29 37 "howToInstallNodejs": "How to install Node.js", 30 38 "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", ··· 35 43 "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 44 "nodejsWithTypescript": "Node.js with TypeScript", 37 45 "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 46 + } 47 + }, 48 + "asynchronousWork": { 49 + "links": { 50 + "asynchronousWork": "Asynchronous Work", 41 51 "asynchronousFlowControl": "Asynchronous flow control", 42 52 "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 53 "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", ··· 45 55 "understandingProcessnexttick": "Understanding process.nextTick()", 46 56 "understandingSetimmediate": "Understanding setImmediate()", 47 57 "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 58 + } 59 + }, 60 + "manipulatingFiles": { 61 + "links": { 62 + "manipulatingFiles": "Manipulating Files", 51 63 "nodejsFileStats": "Node.js file stats", 52 64 "nodejsFilePaths": "Node.js File Paths", 53 65 "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 66 "readingFilesWithNodejs": "Reading files with Node.js", 55 67 "writingFilesWithNodejs": "Writing files with Node.js", 56 68 "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 69 + } 70 + }, 71 + "commandLine": { 72 + "links": { 73 + "commandLine": "Command Line", 60 74 "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 75 "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 76 "howToUseTheNodejsRepl": "How to use the Node.js REPL", ··· 65 79 } 66 80 } 67 81 }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 82 "about": { 75 83 "links": { 84 + "about": "About Node.js", 76 85 "governance": "Project Governance", 77 86 "releases": "Previous Releases", 78 87 "security": "Security Reporting" ··· 80 89 }, 81 90 "docs": { 82 91 "links": { 92 + "docs": "Docs", 83 93 "es6": "ES6 and beyond", 84 94 "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 95 "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 96 + "guides": "Guides <graySpan>ARCHIVE</graySpan>", 87 97 "dependencies": "Dependencies" 88 98 } 89 99 }, 90 100 "getInvolved": { 91 101 "links": { 102 + "getInvolved": "Get Involved", 92 103 "collabSummit": "Collab Summit", 93 104 "contribute": "Contribute", 94 105 "codeOfConduct": "Code of Conduct" ··· 138 149 "nextAriaLabel": "Next page", 139 150 "defaultLabel": "Pagination", 140 151 "pageLabel": "Go to page {pageNumber}" 152 + }, 153 + "sidebar": { 154 + "title": "Change page" 141 155 }, 142 156 "languageDropdown": { 143 157 "label": "Choose Language"
-199
i18n/locales/es.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/fr.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/id.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/it.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/ja.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/ka.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/ko.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/pt-br.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/ru.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/tr.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/uk.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-199
i18n/locales/zh-cn.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - }, 177 - "downloads": { 178 - "changelogModal": { 179 - "startContributing": "Start Contributing" 180 - } 181 - } 182 - }, 183 - "layouts": { 184 - "blogPost": { 185 - "author": { 186 - "byLine": "{author, select, null {} other {By {author}, }}" 187 - } 188 - }, 189 - "blogIndex": { 190 - "currentYear": "News from {year}" 191 - } 192 - }, 193 - "pages": { 194 - "404": { 195 - "title": "404: Page could not be found", 196 - "description": "ENOENT: no such file or directory" 197 - } 198 - } 199 - }
-194
i18n/locales/zh-tw.json
··· 1 - { 2 - "components": { 3 - "footer": { 4 - "scrollToTop": { 5 - "button": "Scroll to top" 6 - }, 7 - "links": { 8 - "trademarkPolicy": "Trademark Policy", 9 - "privacyPolicy": "Privacy Policy", 10 - "codeOfConduct": "Code of Conduct", 11 - "security": "Security Policy", 12 - "openJS": "OpenJS Foundation" 13 - } 14 - }, 15 - "header": { 16 - "links": { 17 - "about": "About", 18 - "download": "Download", 19 - "docs": "Docs", 20 - "getInvolved": "Get Involved", 21 - "security": "Security", 22 - "certification": "Certification", 23 - "blog": "News", 24 - "learn": { 25 - "title": "Learn", 26 - "gettingStarted": { 27 - "title": "Getting Started", 28 - "introductionToNodejs": "Introduction to Node.js", 29 - "howToInstallNodejs": "How to install Node.js", 30 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": "How much JavaScript do you need to know to use Node.js?", 31 - "differencesBetweenNodejsAndTheBrowser": "Differences between Node.js and the Browser", 32 - "theV8JavascriptEngine": "The V8 JavaScript Engine", 33 - "anIntroductionToTheNpmPackageManager": "An introduction to the NPM package manager", 34 - "ecmascript2015Es6AndBeyond": "ECMAScript 2015 (ES6) and beyond", 35 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": "Node.js, the difference between development and production", 36 - "nodejsWithTypescript": "Node.js with TypeScript", 37 - "nodejsWithWebassembly": "Node.js with WebAssembly" 38 - }, 39 - "asynchronousWork": { 40 - "title": "Asynchronous Work", 41 - "asynchronousFlowControl": "Asynchronous flow control", 42 - "overviewOfBlockingVsNonBlocking": "Overview of Blocking vs Non-Blocking", 43 - "javascriptAsynchronousProgrammingAndCallbacks": "JavaScript Asynchronous Programming and Callbacks", 44 - "discoverJavaScriptTimers": "Discover JavaScript Timers", 45 - "understandingProcessnexttick": "Understanding process.nextTick()", 46 - "understandingSetimmediate": "Understanding setImmediate()", 47 - "theNodejsEventEmitter": "The Node.js Event emitter" 48 - }, 49 - "manipulatingFiles": { 50 - "title": "Manipulating Files", 51 - "nodejsFileStats": "Node.js file stats", 52 - "nodejsFilePaths": "Node.js File Paths", 53 - "workingWithFileDescriptorsInNodejs": "Working with file descriptors in Node.js", 54 - "readingFilesWithNodejs": "Reading files with Node.js", 55 - "writingFilesWithNodejs": "Writing files with Node.js", 56 - "workingWithFoldersInNodejs": "Working with folders in Node.js" 57 - }, 58 - "commandLine": { 59 - "title": "Command Line", 60 - "runNodejsScriptsFromTheCommandLine": "Run Node.js scripts from the command line", 61 - "howToReadEnvironmentVariablesFromNodejs": "How to read environment variables from Node.js", 62 - "howToUseTheNodejsRepl": "How to use the Node.js REPL", 63 - "outputToTheCommandLineUsingNodejs": "Output to the command line using Node.js", 64 - "acceptInputFromTheCommandLineInNodejs": "Accept input from the command line in Node.js" 65 - } 66 - } 67 - }, 68 - "buttons": { 69 - "toggleLanguage": "Toggle Language", 70 - "toggleTheme": "Toggle dark/light mode" 71 - } 72 - }, 73 - "navigation": { 74 - "about": { 75 - "links": { 76 - "governance": "Project Governance", 77 - "releases": "Previous Releases", 78 - "security": "Security Reporting" 79 - } 80 - }, 81 - "docs": { 82 - "links": { 83 - "es6": "ES6 and beyond", 84 - "apiLts": "{fullLtsNodeVersion} API <graySpan>LTS</graySpan>", 85 - "apiCurrent": "{fullCurrentNodeVersion} API", 86 - "guides": "Guides <graySpan>ARCHIVED</graySpan>", 87 - "dependencies": "Dependencies" 88 - } 89 - }, 90 - "getInvolved": { 91 - "links": { 92 - "collabSummit": "Collab Summit", 93 - "contribute": "Contribute", 94 - "codeOfConduct": "Code of Conduct" 95 - } 96 - } 97 - }, 98 - "downloadList": { 99 - "links": { 100 - "previousReleases": "Previous Releases", 101 - "packageManager": "Installing Node.js via package manager", 102 - "shaSums": { 103 - "title": "Signed SHASUMS for release files", 104 - "howToVerify": " (How to verify)" 105 - }, 106 - "allDownloads": "All download options", 107 - "nightlyReleases": "Nightly builds", 108 - "unofficialBuilds": "Unofficial builds", 109 - "buildingFromSource": "Building Node.js from source on supported platforms", 110 - "installingOnLinux": "Installing Node.js via binary archive", 111 - "installingOnWsl": "Install on Windows Subsystem for Linux (WSL)" 112 - } 113 - }, 114 - "downloadReleasesTable": { 115 - "changelog": "Changelog", 116 - "releases": "Releases", 117 - "docs": "Docs" 118 - }, 119 - "pagination": { 120 - "next": "Newer | ", 121 - "previous": "Older" 122 - }, 123 - "common": { 124 - "breadcrumbs": { 125 - "navigateToHome": "Navigate to Home" 126 - }, 127 - "crossLink": { 128 - "previous": "Prev", 129 - "next": "Next" 130 - }, 131 - "codebox": { 132 - "copied": "Copied to clipboard!" 133 - }, 134 - "pagination": { 135 - "prev": "Previous", 136 - "prevAriaLabel": "Previous page", 137 - "next": "Next", 138 - "nextAriaLabel": "Next page", 139 - "defaultLabel": "Pagination", 140 - "pageLabel": "Go to page {pageNumber}" 141 - }, 142 - "languageDropdown": { 143 - "label": "Choose Language" 144 - }, 145 - "card": { 146 - "announcement": "Announcements", 147 - "release": "Releases", 148 - "vulnerability": "Vulnerabilities" 149 - } 150 - }, 151 - "metabar": { 152 - "lastUpdated": "Last Updated", 153 - "readingTime": "Reading Time", 154 - "addedIn": "Added In", 155 - "author": "Author", 156 - "authors": "Authors", 157 - "contribute": "Contribute", 158 - "contributeText": "Edit this page", 159 - "viewAs": "View as", 160 - "tableOfContents": "Table of Contents" 161 - }, 162 - "api": { 163 - "jsonLink": { 164 - "title": "View as JSON" 165 - }, 166 - "sourceLink": "Source Code:" 167 - }, 168 - "home": { 169 - "homeDownloadButton": { 170 - "download": "{version} {isLts, select, true {LTS} other {Current}}", 171 - "tagline": "{isLts, select, true {Recommended For Most Users} other {Latest Features}}", 172 - "changelog": "Changelog", 173 - "otherDownloads": "Other Downloads", 174 - "apiDocs": "API Docs" 175 - } 176 - } 177 - }, 178 - "layouts": { 179 - "blogPost": { 180 - "author": { 181 - "byLine": "{author, select, null {} other {By {author}, }}" 182 - } 183 - }, 184 - "blogIndex": { 185 - "currentYear": "News from {year}" 186 - } 187 - }, 188 - "pages": { 189 - "404": { 190 - "title": "404: Page could not be found", 191 - "description": "ENOENT: no such file or directory" 192 - } 193 - } 194 - }
+1
jest.config.mjs
··· 15 15 moduleNameMapper: { 16 16 'next/router': '<rootDir>/components/__mocks__/next-router.mjs', 17 17 'next-intl': '<rootDir>/components/__mocks__/next-intl.mjs', 18 + 'github-slugger': '<rootDir>/components/__mocks__/github-slugger.mjs', 18 19 }, 19 20 }; 20 21
+25
layouts/New/About.tsx
··· 1 + import type { FC, PropsWithChildren } from 'react'; 2 + 3 + import WithBreadcrumbs from '@/components/withBreadcrumbs'; 4 + import WithMetaBar from '@/components/withMetaBar'; 5 + import WithNavBar from '@/components/withNavBar'; 6 + import WithSideBar from '@/components/withSideBar'; 7 + import ArticleLayout from '@/layouts/New/Article'; 8 + 9 + const AboutLayout: FC<PropsWithChildren> = ({ children }) => ( 10 + <> 11 + <WithNavBar /> 12 + 13 + <ArticleLayout> 14 + <WithSideBar keys={['about', 'getInvolved']} /> 15 + 16 + {children} 17 + 18 + <WithMetaBar /> 19 + 20 + <WithBreadcrumbs /> 21 + </ArticleLayout> 22 + </> 23 + ); 24 + 25 + export default AboutLayout;
+9
layouts/New/Article.tsx
··· 1 + import type { FC, PropsWithChildren } from 'react'; 2 + 3 + import styles from './layouts.module.css'; 4 + 5 + const ArticleLayout: FC<PropsWithChildren> = ({ children }) => ( 6 + <article className={styles.articleLayout}>{children}</article> 7 + ); 8 + 9 + export default ArticleLayout;
+9
layouts/New/Base.tsx
··· 1 + import type { FC, PropsWithChildren } from 'react'; 2 + 3 + import styles from './layouts.module.css'; 4 + 5 + const BaseLayout: FC<PropsWithChildren> = ({ children }) => ( 6 + <div className={styles.baseLayout}>{children}</div> 7 + ); 8 + 9 + export default BaseLayout;
+16
layouts/New/Default.tsx
··· 1 + import type { FC, PropsWithChildren } from 'react'; 2 + 3 + import WithFooter from '@/components/withFooter'; 4 + import WithNavBar from '@/components/withNavBar'; 5 + 6 + const DefaultLayout: FC<PropsWithChildren> = ({ children }) => ( 7 + <> 8 + <WithNavBar /> 9 + 10 + {children} 11 + 12 + <WithFooter /> 13 + </> 14 + ); 15 + 16 + export default DefaultLayout;
+62
layouts/New/layouts.module.css
··· 1 + .baseLayout { 2 + @apply grid 3 + h-screen 4 + w-screen 5 + grid-cols-[1fr] 6 + grid-rows-[auto_1fr_auto]; 7 + } 8 + 9 + .articleLayout { 10 + @apply grid 11 + grid-rows-[1fr] 12 + overflow-hidden 13 + grid-areas-[sidebar_main_metabar,sidebar_footer_metabar] 14 + sm:grid-cols-[200px_1fr_200px] 15 + xl:grid-cols-[320px_1fr_320px] 16 + xs:block 17 + xs:overflow-auto; 18 + 19 + > *:nth-child(1) { 20 + @apply grid-in-[sidebar]; 21 + } 22 + 23 + > *:nth-child(2) { 24 + @apply flex 25 + w-full 26 + flex-col 27 + items-start 28 + gap-6 29 + self-stretch 30 + overflow-y-auto 31 + overflow-x-hidden 32 + bg-gradient-subtle 33 + p-12 34 + grid-in-[main] 35 + dark:bg-gradient-subtle-dark 36 + xl:px-[4.5rem] 37 + xs:bg-none 38 + xs:p-4 39 + xs:dark:bg-none; 40 + } 41 + 42 + > *:nth-child(3) { 43 + @apply grid-in-[metabar]; 44 + } 45 + 46 + > *:nth-child(4) { 47 + @apply sticky 48 + bottom-0 49 + flex 50 + w-full 51 + flex-col 52 + items-center 53 + self-stretch 54 + border-t 55 + border-t-neutral-200 56 + bg-white 57 + py-4 58 + grid-in-[footer] 59 + dark:border-t-neutral-900 60 + dark:bg-neutral-950; 61 + } 62 + }
+268 -245
navigation.json
··· 1 1 { 2 - "about": { 3 - "link": "/about", 4 - "translationId": "components.header.links.about", 5 - "items": { 6 - "governance": { 7 - "link": "/about/governance", 8 - "translationId": "components.navigation.about.links.governance" 9 - }, 10 - "releases": { 11 - "link": "/about/previous-releases", 12 - "translationId": "components.navigation.about.links.releases" 13 - }, 14 - "security": { 15 - "link": "/about/security-reporting", 16 - "translationId": "components.navigation.about.links.security" 17 - } 2 + "topNavigation": { 3 + "learn": { 4 + "link": "/learn", 5 + "label": "components.header.links.learn" 6 + }, 7 + "about": { 8 + "link": "/about", 9 + "label": "components.header.links.about" 10 + }, 11 + "getInvolved": { 12 + "link": "/get-involved", 13 + "label": "components.header.links.getInvolved" 14 + }, 15 + "docs": { 16 + "link": "/docs", 17 + "label": "components.header.links.docs" 18 + }, 19 + "download": { 20 + "link": "/download", 21 + "label": "components.header.links.download" 22 + }, 23 + "blog": { 24 + "link": "/blog", 25 + "label": "components.header.links.blog" 26 + }, 27 + "certification": { 28 + "link": "https://openjsf.org/certification", 29 + "label": "components.header.links.certification" 18 30 } 19 31 }, 20 - "learn": { 21 - "link": "/learn", 22 - "translationId": "components.header.links.learn.title", 23 - "items": { 24 - "gettingStarted": { 25 - "link": "/learn/getting-started/introduction-to-nodejs", 26 - "translationId": "components.header.links.learn.gettingStarted.title", 27 - "items": { 28 - "introductionToNodejs": { 29 - "link": "/learn/getting-started/introduction-to-nodejs", 30 - "translationId": "components.header.links.learn.gettingStarted.introductionToNodejs" 31 - }, 32 - "howToInstallNodejs": { 33 - "link": "/learn/getting-started/how-to-install-nodejs", 34 - "translationId": "components.header.links.learn.gettingStarted.howToInstallNodejs" 35 - }, 36 - "howMuchJavascriptDoYouNeedToKnowToUseNodejs": { 37 - "link": "/learn/getting-started/how-much-javascript-do-you-need-to-know-to-use-nodejs", 38 - "translationId": "components.header.links.learn.gettingStarted.howMuchJavascriptDoYouNeedToKnowToUseNodejs" 39 - }, 40 - "differencesBetweenNodejsAndTheBrowser": { 41 - "link": "/learn/getting-started/differences-between-nodejs-and-the-browser", 42 - "translationId": "components.header.links.learn.gettingStarted.differencesBetweenNodejsAndTheBrowser" 43 - }, 44 - "theV8JavascriptEngine": { 45 - "link": "/learn/getting-started/the-v8-javascript-engine", 46 - "translationId": "components.header.links.learn.gettingStarted.theV8JavascriptEngine" 47 - }, 48 - "anIntroductionToTheNpmPackageManager": { 49 - "link": "/learn/getting-started/an-introduction-to-the-npm-package-manager", 50 - "translationId": "components.header.links.learn.gettingStarted.anIntroductionToTheNpmPackageManager" 51 - }, 52 - "ecmascript2015Es6AndBeyond": { 53 - "link": "/learn/getting-started/ecmascript-2015-es6-and-beyond", 54 - "translationId": "components.header.links.learn.gettingStarted.ecmascript2015Es6AndBeyond" 55 - }, 56 - "nodejsTheDifferenceBetweenDevelopmentAndProduction": { 57 - "link": "/learn/getting-started/nodejs-the-difference-between-development-and-production", 58 - "translationId": "components.header.links.learn.gettingStarted.nodejsTheDifferenceBetweenDevelopmentAndProduction" 59 - }, 60 - "nodejsWithTypescript": { 61 - "link": "/learn/getting-started/nodejs-with-typescript", 62 - "translationId": "components.header.links.learn.gettingStarted.nodejsWithTypescript" 63 - }, 64 - "nodejsWithWebassembly": { 65 - "link": "/learn/getting-started/nodejs-with-webassembly", 66 - "translationId": "components.header.links.learn.gettingStarted.nodejsWithWebassembly" 32 + "sideNavigation": { 33 + "about": { 34 + "label": "components.navigation.about.links.about", 35 + "items": { 36 + "about": { 37 + "link": "/about", 38 + "label": "components.navigation.about.links.about" 39 + }, 40 + "governance": { 41 + "link": "/about/governance", 42 + "label": "components.navigation.about.links.governance" 43 + }, 44 + "releases": { 45 + "link": "/about/previous-releases", 46 + "label": "components.navigation.about.links.releases" 47 + }, 48 + "security": { 49 + "link": "/about/security-reporting", 50 + "label": "components.navigation.about.links.security" 51 + } 52 + } 53 + }, 54 + "getInvolved": { 55 + "label": "components.navigation.getInvolved.links.getInvolved", 56 + "items": { 57 + "getInvolved": { 58 + "link": "/get-involved", 59 + "label": "components.navigation.getInvolved.links.getInvolved" 60 + }, 61 + "collabSummit": { 62 + "link": "/get-involved/collab-summit", 63 + "label": "components.navigation.getInvolved.links.collabSummit" 64 + }, 65 + "contribute": { 66 + "link": "/get-involved/contribute", 67 + "label": "components.navigation.getInvolved.links.contribute" 68 + }, 69 + "codeOfConduct": { 70 + "link": "https://github.com/nodejs/node/blob/main/doc/contributing/code-of-conduct.md", 71 + "label": "components.navigation.getInvolved.links.codeOfConduct" 72 + } 73 + } 74 + }, 75 + "docs": { 76 + "label": "components.navigation.docs.links.docs", 77 + "items": { 78 + "docs": { 79 + "link": "/docs", 80 + "label": "components.navigation.docs.links.docs" 81 + }, 82 + "apiLts": { 83 + "link": "https://nodejs.org/dist/latest-{ltsNodeVersion}/docs/api", 84 + "label": "components.navigation.docs.links.apiLts" 85 + }, 86 + "apiCurrent": { 87 + "link": "https://nodejs.org/dist/latest-{currentNodeVersion}/docs/api", 88 + "label": "components.navigation.docs.links.apiCurrent" 89 + }, 90 + "es6": { 91 + "link": "/docs/es6", 92 + "label": "components.navigation.docs.links.es6" 93 + }, 94 + "guides": { 95 + "link": "/docs/guides", 96 + "label": "components.navigation.docs.links.guides" 97 + }, 98 + "dependencies": { 99 + "link": "https://github.com/nodejs/node/blob/main/doc/contributing/maintaining/maintaining-dependencies.md", 100 + "label": "components.navigation.docs.links.dependencies" 101 + } 102 + } 103 + }, 104 + "learn": { 105 + "items": { 106 + "gettingStarted": { 107 + "label": "components.navigation.learn.gettingStarted.links.gettingStarted", 108 + "items": { 109 + "introductionToNodejs": { 110 + "link": "/learn/getting-started/introduction-to-nodejs", 111 + "label": "components.navigation.learn.gettingStarted.links.introductionToNodejs" 112 + }, 113 + "howToInstallNodejs": { 114 + "link": "/learn/getting-started/how-to-install-nodejs", 115 + "label": "components.navigation.learn.gettingStarted.links.howToInstallNodejs" 116 + }, 117 + "howMuchJavascriptDoYouNeedToKnowToUseNodejs": { 118 + "link": "/learn/getting-started/how-much-javascript-do-you-need-to-know-to-use-nodejs", 119 + "label": "components.navigation.learn.gettingStarted.links.howMuchJavascriptDoYouNeedToKnowToUseNodejs" 120 + }, 121 + "differencesBetweenNodejsAndTheBrowser": { 122 + "link": "/learn/getting-started/differences-between-nodejs-and-the-browser", 123 + "label": "components.navigation.learn.gettingStarted.links.differencesBetweenNodejsAndTheBrowser" 124 + }, 125 + "theV8JavascriptEngine": { 126 + "link": "/learn/getting-started/the-v8-javascript-engine", 127 + "label": "components.navigation.learn.gettingStarted.links.theV8JavascriptEngine" 128 + }, 129 + "anIntroductionToTheNpmPackageManager": { 130 + "link": "/learn/getting-started/an-introduction-to-the-npm-package-manager", 131 + "label": "components.navigation.learn.gettingStarted.links.anIntroductionToTheNpmPackageManager" 132 + }, 133 + "ecmascript2015Es6AndBeyond": { 134 + "link": "/learn/getting-started/ecmascript-2015-es6-and-beyond", 135 + "label": "components.navigation.learn.gettingStarted.links.ecmascript2015Es6AndBeyond" 136 + }, 137 + "nodejsTheDifferenceBetweenDevelopmentAndProduction": { 138 + "link": "/learn/getting-started/nodejs-the-difference-between-development-and-production", 139 + "label": "components.navigation.learn.gettingStarted.links.nodejsTheDifferenceBetweenDevelopmentAndProduction" 140 + }, 141 + "nodejsWithTypescript": { 142 + "link": "/learn/getting-started/nodejs-with-typescript", 143 + "label": "components.navigation.learn.gettingStarted.links.nodejsWithTypescript" 144 + }, 145 + "nodejsWithWebassembly": { 146 + "link": "/learn/getting-started/nodejs-with-webassembly", 147 + "label": "components.navigation.learn.gettingStarted.links.nodejsWithWebassembly" 148 + } 67 149 } 68 - } 69 - }, 70 - "asynchronousWork": { 71 - "link": "/learn/asynchronous-work/asynchronous-flow-control", 72 - "translationId": "components.header.links.learn.asynchronousWork.title", 73 - "items": { 74 - "asynchronousFlowControl": { 75 - "link": "/learn/asynchronous-work/asynchronous-flow-control", 76 - "translationId": "components.header.links.learn.asynchronousWork.asynchronousFlowControl" 77 - }, 78 - "overviewOfBlockingVsNonBlocking": { 79 - "link": "/learn/asynchronous-work/overview-of-blocking-vs-non-blocking", 80 - "translationId": "components.header.links.learn.asynchronousWork.overviewOfBlockingVsNonBlocking" 81 - }, 82 - "javascriptAsynchronousProgrammingAndCallbacks": { 83 - "link": "/learn/asynchronous-work/javascript-asynchronous-programming-and-callbacks", 84 - "translationId": "components.header.links.learn.asynchronousWork.javascriptAsynchronousProgrammingAndCallbacks" 85 - }, 86 - "discoverJavaScriptTimers": { 87 - "link": "/learn/asynchronous-work/discover-javascript-timers", 88 - "translationId": "components.header.links.learn.asynchronousWork.discoverJavaScriptTimers" 89 - }, 90 - "understandingProcessnexttick": { 91 - "link": "/learn/asynchronous-work/understanding-processnexttick", 92 - "translationId": "components.header.links.learn.asynchronousWork.understandingProcessnexttick" 93 - }, 94 - "understandingSetimmediate": { 95 - "link": "/learn/asynchronous-work/understanding-setimmediate", 96 - "translationId": "components.header.links.learn.asynchronousWork.understandingSetimmediate" 97 - }, 98 - "theNodejsEventEmitter": { 99 - "link": "/learn/asynchronous-work/the-nodejs-event-emitter", 100 - "translationId": "components.header.links.learn.asynchronousWork.theNodejsEventEmitter" 150 + }, 151 + "asynchronousWork": { 152 + "label": "components.navigation.learn.asynchronousWork.links.asynchronousWork", 153 + "items": { 154 + "asynchronousFlowControl": { 155 + "link": "/learn/asynchronous-work/asynchronous-flow-control", 156 + "label": "components.navigation.learn.asynchronousWork.links.asynchronousFlowControl" 157 + }, 158 + "overviewOfBlockingVsNonBlocking": { 159 + "link": "/learn/asynchronous-work/overview-of-blocking-vs-non-blocking", 160 + "label": "components.navigation.learn.asynchronousWork.links.overviewOfBlockingVsNonBlocking" 161 + }, 162 + "javascriptAsynchronousProgrammingAndCallbacks": { 163 + "link": "/learn/asynchronous-work/javascript-asynchronous-programming-and-callbacks", 164 + "label": "components.navigation.learn.asynchronousWork.links.javascriptAsynchronousProgrammingAndCallbacks" 165 + }, 166 + "discoverJavaScriptTimers": { 167 + "link": "/learn/asynchronous-work/discover-javascript-timers", 168 + "label": "components.navigation.learn.asynchronousWork.links.discoverJavaScriptTimers" 169 + }, 170 + "understandingProcessnexttick": { 171 + "link": "/learn/asynchronous-work/understanding-processnexttick", 172 + "label": "components.navigation.learn.asynchronousWork.links.understandingProcessnexttick" 173 + }, 174 + "understandingSetimmediate": { 175 + "link": "/learn/asynchronous-work/understanding-setimmediate", 176 + "label": "components.navigation.learn.asynchronousWork.links.understandingSetimmediate" 177 + }, 178 + "theNodejsEventEmitter": { 179 + "link": "/learn/asynchronous-work/the-nodejs-event-emitter", 180 + "label": "components.navigation.learn.asynchronousWork.links.theNodejsEventEmitter" 181 + } 101 182 } 102 - } 103 - }, 104 - "manipulatingFiles": { 105 - "link": "/learn/manipulating-files/nodejs-file-stats", 106 - "translationId": "components.header.links.learn.manipulatingFiles.title", 107 - "items": { 108 - "nodejsFileStats": { 109 - "link": "/learn/manipulating-files/nodejs-file-stats", 110 - "translationId": "components.header.links.learn.manipulatingFiles.nodejsFileStats" 111 - }, 112 - "nodejsFilePaths": { 113 - "link": "/learn/manipulating-files/nodejs-file-paths", 114 - "translationId": "components.header.links.learn.manipulatingFiles.nodejsFilePaths" 115 - }, 116 - "workingWithFileDescriptorsInNodejs": { 117 - "link": "/learn/manipulating-files/working-with-file-descriptors-in-nodejs", 118 - "translationId": "components.header.links.learn.manipulatingFiles.workingWithFileDescriptorsInNodejs" 119 - }, 120 - "readingFilesWithNodejs": { 121 - "link": "/learn/manipulating-files/reading-files-with-nodejs", 122 - "translationId": "components.header.links.learn.manipulatingFiles.readingFilesWithNodejs" 123 - }, 124 - "writingFilesWithNodejs": { 125 - "link": "/learn/manipulating-files/writing-files-with-nodejs", 126 - "translationId": "components.header.links.learn.manipulatingFiles.writingFilesWithNodejs" 127 - }, 128 - "workingWithFoldersInNodejs": { 129 - "link": "/learn/manipulating-files/working-with-folders-in-nodejs", 130 - "translationId": "components.header.links.learn.manipulatingFiles.workingWithFoldersInNodejs" 183 + }, 184 + "manipulatingFiles": { 185 + "label": "components.navigation.learn.manipulatingFiles.links.manipulatingFiles", 186 + "items": { 187 + "nodejsFileStats": { 188 + "link": "/learn/manipulating-files/nodejs-file-stats", 189 + "label": "components.navigation.learn.manipulatingFiles.links.nodejsFileStats" 190 + }, 191 + "nodejsFilePaths": { 192 + "link": "/learn/manipulating-files/nodejs-file-paths", 193 + "label": "components.navigation.learn.manipulatingFiles.links.nodejsFilePaths" 194 + }, 195 + "workingWithFileDescriptorsInNodejs": { 196 + "link": "/learn/manipulating-files/working-with-file-descriptors-in-nodejs", 197 + "label": "components.navigation.learn.manipulatingFiles.links.workingWithFileDescriptorsInNodejs" 198 + }, 199 + "readingFilesWithNodejs": { 200 + "link": "/learn/manipulating-files/reading-files-with-nodejs", 201 + "label": "components.navigation.learn.manipulatingFiles.links.readingFilesWithNodejs" 202 + }, 203 + "writingFilesWithNodejs": { 204 + "link": "/learn/manipulating-files/writing-files-with-nodejs", 205 + "label": "components.navigation.learn.manipulatingFiles.links.writingFilesWithNodejs" 206 + }, 207 + "workingWithFoldersInNodejs": { 208 + "link": "/learn/manipulating-files/working-with-folders-in-nodejs", 209 + "label": "components.navigation.learn.manipulatingFiles.links.workingWithFoldersInNodejs" 210 + } 131 211 } 132 - } 133 - }, 134 - "commandLine": { 135 - "link": "/learn/command-line/run-nodejs-scripts-from-the-command-line", 136 - "translationId": "components.header.links.learn.commandLine.title", 137 - "items": { 138 - "runNodejsScriptsFromTheCommandLine": { 139 - "link": "/learn/command-line/run-nodejs-scripts-from-the-command-line", 140 - "translationId": "components.header.links.learn.commandLine.runNodejsScriptsFromTheCommandLine" 141 - }, 142 - "howToReadEnvironmentVariablesFromNodejs": { 143 - "link": "/learn/command-line/how-to-read-environment-variables-from-nodejs", 144 - "translationId": "components.header.links.learn.commandLine.howToReadEnvironmentVariablesFromNodejs" 145 - }, 146 - "howToUseTheNodejsRepl": { 147 - "link": "/learn/command-line/how-to-use-the-nodejs-repl", 148 - "translationId": "components.header.links.learn.commandLine.howToUseTheNodejsRepl" 149 - }, 150 - "outputToTheCommandLineUsingNodejs": { 151 - "link": "/learn/command-line/output-to-the-command-line-using-nodejs", 152 - "translationId": "components.header.links.learn.commandLine.outputToTheCommandLineUsingNodejs" 153 - }, 154 - "acceptInputFromTheCommandLineInNodejs": { 155 - "link": "/learn/command-line/accept-input-from-the-command-line-in-nodejs", 156 - "translationId": "components.header.links.learn.commandLine.acceptInputFromTheCommandLineInNodejs" 212 + }, 213 + "commandLine": { 214 + "label": "components.navigation.learn.commandLine.links.commandLine", 215 + "items": { 216 + "runNodejsScriptsFromTheCommandLine": { 217 + "link": "/learn/command-line/run-nodejs-scripts-from-the-command-line", 218 + "label": "components.navigation.learn.commandLine.links.runNodejsScriptsFromTheCommandLine" 219 + }, 220 + "howToReadEnvironmentVariablesFromNodejs": { 221 + "link": "/learn/command-line/how-to-read-environment-variables-from-nodejs", 222 + "label": "components.navigation.learn.commandLine.links.howToReadEnvironmentVariablesFromNodejs" 223 + }, 224 + "howToUseTheNodejsRepl": { 225 + "link": "/learn/command-line/how-to-use-the-nodejs-repl", 226 + "label": "components.navigation.learn.commandLine.links.howToUseTheNodejsRepl" 227 + }, 228 + "outputToTheCommandLineUsingNodejs": { 229 + "link": "/learn/command-line/output-to-the-command-line-using-nodejs", 230 + "label": "components.navigation.learn.commandLine.links.outputToTheCommandLineUsingNodejs" 231 + }, 232 + "acceptInputFromTheCommandLineInNodejs": { 233 + "link": "/learn/command-line/accept-input-from-the-command-line-in-nodejs", 234 + "label": "components.navigation.learn.commandLine.links.acceptInputFromTheCommandLineInNodejs" 235 + } 157 236 } 158 237 } 159 238 } 160 - } 161 - }, 162 - "download": { 163 - "link": "/download", 164 - "translationId": "components.header.links.download", 165 - "items": { 166 - "shaSums": { 167 - "link": "https://nodejs.org/dist/{nodeVersion}/SHASUMS256.txt.asc", 168 - "translationId": "components.downloadList.links.shaSums.title" 169 - }, 170 - "allDownloads": { 171 - "link": "https://nodejs.org/dist/{nodeVersion}/", 172 - "translationId": "components.downloadList.links.allDownloads" 173 - }, 174 - "packageManager": { 175 - "link": "/download/package-manager", 176 - "translationId": "components.downloadList.links.packageManager" 177 - }, 178 - "previousReleases": { 179 - "link": "/about/previous-releases", 180 - "translationId": "components.downloadList.links.previousReleases" 181 - }, 182 - "nightlyReleases": { 183 - "link": "https://nodejs.org/download/nightly/", 184 - "translationId": "components.downloadList.links.nightlyReleases" 185 - }, 186 - "unofficialBuilds": { 187 - "link": "https://unofficial-builds.nodejs.org/download/", 188 - "translationId": "components.downloadList.links.unofficialBuilds" 189 - }, 190 - "buildingFromSource": { 191 - "link": "https://github.com/nodejs/node/blob/main/BUILDING.md#building-nodejs-on-supported-platforms", 192 - "translationId": "components.downloadList.links.buildingFromSource" 193 - }, 194 - "installingOnLinux": { 195 - "link": "https://github.com/nodejs/help/wiki/Installation", 196 - "translationId": "components.downloadList.links.installingOnLinux" 197 - }, 198 - "installingOnWsl": { 199 - "link": "https://github.com/nodejs/node/blob/main/BUILDING.md#building-nodejs-on-supported-platforms", 200 - "translationId": "components.downloadList.links.installingOnWsl" 201 - } 202 - } 203 - }, 204 - "docs": { 205 - "link": "/docs", 206 - "translationId": "components.header.links.docs", 207 - "items": { 208 - "apiLts": { 209 - "link": "https://nodejs.org/dist/latest-{ltsNodeVersion}/docs/api", 210 - "translationId": "components.navigation.docs.links.apiLts" 211 - }, 212 - "apiCurrent": { 213 - "link": "https://nodejs.org/dist/latest-{currentNodeVersion}/docs/api", 214 - "translationId": "components.navigation.docs.links.apiCurrent" 215 - }, 216 - "es6": { 217 - "link": "/docs/es6", 218 - "translationId": "components.navigation.docs.links.es6" 219 - }, 220 - "guides": { 221 - "link": "/docs/guides", 222 - "translationId": "components.navigation.docs.links.guides" 223 - }, 224 - "dependencies": { 225 - "link": "https://github.com/nodejs/node/blob/main/doc/contributing/maintaining/maintaining-dependencies.md", 226 - "translationId": "components.navigation.docs.links.dependencies" 227 - } 228 - } 229 - }, 230 - "getInvolved": { 231 - "link": "/get-involved", 232 - "translationId": "components.header.links.getInvolved", 233 - "items": { 234 - "collabSummit": { 235 - "link": "/get-involved/collab-summit", 236 - "translationId": "components.navigation.getInvolved.links.collabSummit" 237 - }, 238 - "contribute": { 239 - "link": "/get-involved/contribute", 240 - "translationId": "components.navigation.getInvolved.links.contribute" 241 - }, 242 - "codeOfConduct": { 243 - "link": "https://github.com/nodejs/node/blob/main/doc/contributing/code-of-conduct.md", 244 - "translationId": "components.navigation.getInvolved.links.codeOfConduct" 239 + }, 240 + "download": { 241 + "items": { 242 + "shaSums": { 243 + "link": "https://nodejs.org/dist/{nodeVersion}/SHASUMS256.txt.asc", 244 + "label": "components.downloadList.links.shaSums.title" 245 + }, 246 + "allDownloads": { 247 + "link": "https://nodejs.org/dist/{nodeVersion}/", 248 + "label": "components.downloadList.links.allDownloads" 249 + }, 250 + "packageManager": { 251 + "link": "/download/package-manager", 252 + "label": "components.downloadList.links.packageManager" 253 + }, 254 + "previousReleases": { 255 + "link": "/about/previous-releases", 256 + "label": "components.downloadList.links.previousReleases" 257 + }, 258 + "nightlyReleases": { 259 + "link": "https://nodejs.org/download/nightly/", 260 + "label": "components.downloadList.links.nightlyReleases" 261 + }, 262 + "unofficialBuilds": { 263 + "link": "https://unofficial-builds.nodejs.org/download/", 264 + "label": "components.downloadList.links.unofficialBuilds" 265 + }, 266 + "buildingFromSource": { 267 + "link": "https://github.com/nodejs/node/blob/main/BUILDING.md#building-nodejs-on-supported-platforms", 268 + "label": "components.downloadList.links.buildingFromSource" 269 + }, 270 + "installingOnLinux": { 271 + "link": "https://github.com/nodejs/help/wiki/Installation", 272 + "label": "components.downloadList.links.installingOnLinux" 273 + }, 274 + "installingOnWsl": { 275 + "link": "https://github.com/nodejs/node/blob/main/BUILDING.md#building-nodejs-on-supported-platforms", 276 + "label": "components.downloadList.links.installingOnWsl" 277 + } 245 278 } 246 279 } 247 - }, 248 - "certification": { 249 - "link": "https://openjsf.org/certification", 250 - "translationId": "components.header.links.certification", 251 - "items": {} 252 - }, 253 - "blog": { 254 - "link": "/blog", 255 - "translationId": "components.header.links.blog", 256 - "items": {} 257 280 } 258 281 }
+1 -1
next-data/generators/releaseData.mjs
··· 55 55 major: latestVersion.semver.major, 56 56 version: latestVersion.semver.raw, 57 57 versionWithPrefix: `v${latestVersion.semver.raw}`, 58 - codename: major.codename || '', 58 + codename: major.support.codename || '', 59 59 isLts: status === 'Active LTS' || status === 'Maintenance LTS', 60 60 npm: latestVersion.dependencies.npm || '', 61 61 v8: latestVersion.dependencies.v8 || '',
+25
next.config.mjs
··· 1 1 'use strict'; 2 2 3 + import { resolve } from 'node:path'; 4 + 3 5 import { withSentryConfig } from '@sentry/nextjs'; 4 6 import withNextIntl from 'next-intl/plugin'; 5 7 6 8 import { 7 9 BASE_PATH, 8 10 ENABLE_STATIC_EXPORT, 11 + ENABLE_WEBSITE_REDESIGN, 9 12 SENTRY_DSN, 10 13 SENTRY_ENABLE, 11 14 SENTRY_EXTENSIONS, ··· 60 63 // Tree-shakes modules from Sentry Bundle 61 64 config.plugins.push(new webpack.DefinePlugin(SENTRY_EXTENSIONS)); 62 65 66 + // This allows us to customise our global styles on build-tim,e 67 + // based on if we're running the Website Redesign or not 68 + config.resolve.alias = { 69 + ...config.resolve.alias, 70 + // @deprecated remove when website redesign is done 71 + globalStyles$: resolve( 72 + ENABLE_WEBSITE_REDESIGN 73 + ? './styles/new/index.css' 74 + : './styles/old/index.css' 75 + ), 76 + }; 77 + 63 78 return config; 64 79 }, 65 80 experimental: { 81 + turbo: { 82 + resolveAlias: { 83 + // This allows us to customise our global styles on build-tim,e 84 + // based on if we're running the Website Redesign or not 85 + // @deprecated remove when website redesign is done 86 + globalStyles: ENABLE_WEBSITE_REDESIGN 87 + ? './styles/new/index.css' 88 + : './styles/old/index.css', 89 + }, 90 + }, 66 91 // Some of our static pages from `getStaticProps` have a lot of data 67 92 // since we pass the fully-compiled MDX page from `MDXRemote` through 68 93 // a page's static props.
+11 -2
next.constants.mjs
··· 40 40 * Note that this is a manual Environment Variable defined by us during `npm run deploy` 41 41 */ 42 42 export const ENABLE_STATIC_EXPORT = 43 - process.env.NEXT_STATIC_EXPORT === 'true' || 44 - process.env.NEXT_STATIC_EXPORT === true; 43 + process.env.NEXT_PUBLIC_STATIC_EXPORT === 'true' || 44 + process.env.NEXT_PUBLIC_STATIC_EXPORT === true; 45 + 46 + /** 47 + * This is used for enabling the New Website Redesign Layouts 48 + * 49 + * Note that this is a manual Environment Variable defined by us if necessary. 50 + */ 51 + export const ENABLE_WEBSITE_REDESIGN = 52 + process.env.NEXT_PUBLIC_ENABLE_REDESIGN === 'true' || 53 + process.env.NEXT_PUBLIC_ENABLE_REDESIGN === true; 45 54 46 55 /** 47 56 * 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.
+29
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 + }); 11 + 12 + // This configures the Next.js Font for Open Sans 13 + // We then export a variable and class name to be used 14 + // within Tailwind (tailwind.config.ts) and Storybook (preview.js) 15 + export const OPEN_SANS = Open_Sans({ 16 + weight: ['300', '400', '600', '700'], 17 + display: 'fallback', 18 + subsets: ['latin'], 19 + variable: '--font-open-sans', 20 + }); 21 + 22 + // This configures the Next.js Font for IBM Plex Mono 23 + // We then export a variable and class name to be used 24 + // within Tailwind (tailwind.config.ts) and Storybook (preview.js) 25 + export const IBM_PLEX_MONO = IBM_Plex_Mono({ 26 + weight: ['600'], 27 + subsets: ['latin'], 28 + variable: '--font-ibm-plex-mono', 29 + });
+1 -1
next.json.mjs
··· 4 4 import _siteRedirects from './redirects.json' assert { type: 'json' }; 5 5 import _siteConfig from './site.json' assert { type: 'json' }; 6 6 7 - /** @type {Record<string, import('./types').NavigationEntry>} */ 7 + /** @type {import('./types').SiteNavigation} */ 8 8 export const siteNavigation = _siteNavigation; 9 9 10 10 /** @type {Record<string, import('./types').Redirect[]>} */
+16 -3
next.mdx.compiler.mjs
··· 5 5 import { matter } from 'vfile-matter'; 6 6 7 7 import { NEXT_REHYPE_PLUGINS, NEXT_REMARK_PLUGINS } from './next.mdx.mjs'; 8 + import { createGitHubSlug } from './util/gitHubUtils'; 8 9 9 10 /** 10 11 * This is our custom simple MDX Compiler that is used to compile Markdown and MDX ··· 12 13 * 13 14 * @param {import('vfile').VFile} source 14 15 * @param {'md' | 'mdx'} fileExtension 15 - * @returns {Promise<{ MDXContent: import('mdx/types').MDXContent; headings: import('@vcarl/remark-headings').Heading[]; frontmatter: Record<string, any>}>} 16 + * @returns {Promise<{ 17 + * MDXContent: import('mdx/types').MDXContent; 18 + * headings: import('@vcarl/remark-headings').Heading[]; 19 + * frontmatter: Record<string, any>, readingTime: import('reading-time').ReadTimeResults 20 + * }>} 16 21 */ 17 22 export async function compileMDX(source, fileExtension) { 18 23 // Parses the Frontmatter to the VFile and removes from the original source 19 24 // cleaning the frontmatter to the source that is going to be parsed by the MDX Compiler 20 25 matter(source, { strip: true }); 26 + 27 + const slugger = createGitHubSlug(); 21 28 22 29 // This is a minimal MDX Compiler that is lightweight and only parses the MDX 23 30 const { default: MDXContent } = await evaluate(source, { ··· 30 37 31 38 // Retrieve some parsed data from the VFile metadata 32 39 // such as frontmatter and Markdown headings 33 - const { headings, matter: frontmatter } = source.data; 40 + const { headings, matter: frontmatter, readingTime } = source.data; 41 + 42 + headings.forEach(heading => { 43 + // we re-sluggify the links to match the GitHub slugger 44 + // since some also do not come with sluggifed links 45 + heading.data = { ...heading.data, id: slugger(heading.value) }; 46 + }); 34 47 35 - return { MDXContent, headings, frontmatter }; 48 + return { MDXContent, headings, frontmatter, readingTime }; 36 49 }
+2 -1
next.mdx.mjs
··· 4 4 import rehypeAutolinkHeadings from 'rehype-autolink-headings'; 5 5 import rehypeSlug from 'rehype-slug'; 6 6 import remarkGfm from 'remark-gfm'; 7 + import readingTime from 'remark-reading-time'; 7 8 8 9 import rehypeShikiji from './next.mdx.shiki.mjs'; 9 10 ··· 26 27 * 27 28 * @type {import('unified').Plugin[]} 28 29 */ 29 - export const NEXT_REMARK_PLUGINS = [remarkGfm, remarkHeadings]; 30 + export const NEXT_REMARK_PLUGINS = [remarkGfm, remarkHeadings, readingTime];
+110 -3
package-lock.json
··· 1 1 { 2 - "name": "nodejs-org-fork", 2 + "name": "nodejs.org", 3 3 "lockfileVersion": 3, 4 4 "requires": true, 5 5 "packages": { ··· 17 17 "@radix-ui/react-select": "^2.0.0", 18 18 "@radix-ui/react-tabs": "^1.0.4", 19 19 "@radix-ui/react-toast": "^1.1.5", 20 + "@savvywombat/tailwindcss-grid-areas": "~3.1.0", 20 21 "@sentry/nextjs": "~7.84.0", 21 22 "@types/node": "20.8.10", 22 23 "@vcarl/remark-headings": "~0.1.0", ··· 25 26 "classnames": "~2.3.2", 26 27 "cross-env": "7.0.3", 27 28 "feed": "~4.2.2", 29 + "github-slugger": "~2.0.0", 28 30 "glob": "~10.3.10", 29 31 "gray-matter": "~4.0.3", 30 32 "husky": "8.0.3", ··· 42 44 "rehype-autolink-headings": "~7.1.0", 43 45 "rehype-slug": "~6.0.0", 44 46 "remark-gfm": "~4.0.0", 47 + "remark-reading-time": "~2.0.1", 45 48 "semver": "~7.5.4", 46 49 "sharp": "0.32.6", 47 50 "shikiji": "~0.7.3", ··· 5276 5279 "resolved": "https://registry.npmjs.org/@rushstack/eslint-patch/-/eslint-patch-1.6.0.tgz", 5277 5280 "integrity": "sha512-2/U3GXA6YiPYQDLGwtGlnNgKYBSwCFIHf8Y9LUY5VATHdtbLlU0Y1R3QoBnT0aB4qv/BEiVVsj7LJXoQCgJ2vA==", 5278 5281 "dev": true 5282 + }, 5283 + "node_modules/@savvywombat/tailwindcss-grid-areas": { 5284 + "version": "3.1.0", 5285 + "resolved": "https://registry.npmjs.org/@savvywombat/tailwindcss-grid-areas/-/tailwindcss-grid-areas-3.1.0.tgz", 5286 + "integrity": "sha512-CaNoCS7Zr3OeDDhCSXXU7dnqYjehdjNmDy6NdFxkLAyDcxA8YTI3rjPm6X+bTWyYINHXr+RONG3UKWrSv2UYSw==", 5287 + "dependencies": { 5288 + "lodash": "^4.17.21" 5289 + }, 5290 + "engines": { 5291 + "node": ">=14.18.2" 5292 + }, 5293 + "peerDependencies": { 5294 + "tailwindcss": "^3.0.1" 5295 + } 5279 5296 }, 5280 5297 "node_modules/@sentry-internal/tracing": { 5281 5298 "version": "7.84.0", ··· 14768 14785 "url": "https://opencollective.com/unified" 14769 14786 } 14770 14787 }, 14788 + "node_modules/estree-util-value-to-estree": { 14789 + "version": "1.3.0", 14790 + "resolved": "https://registry.npmjs.org/estree-util-value-to-estree/-/estree-util-value-to-estree-1.3.0.tgz", 14791 + "integrity": "sha512-Y+ughcF9jSUJvncXwqRageavjrNPAI+1M/L3BI3PyLp1nmgYTGUXU6t5z1Y7OWuThoDdhPME07bQU+d5LxdJqw==", 14792 + "dependencies": { 14793 + "is-plain-obj": "^3.0.0" 14794 + }, 14795 + "engines": { 14796 + "node": ">=12.0.0" 14797 + } 14798 + }, 14799 + "node_modules/estree-util-value-to-estree/node_modules/is-plain-obj": { 14800 + "version": "3.0.0", 14801 + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-3.0.0.tgz", 14802 + "integrity": "sha512-gwsOE28k+23GP1B6vFl1oVh/WOzmawBrKwo5Ev6wMKzPkaXaCDIQKzLnvsA42DRlbVTWorkgTKIviAKCWkfUwA==", 14803 + "engines": { 14804 + "node": ">=10" 14805 + }, 14806 + "funding": { 14807 + "url": "https://github.com/sponsors/sindresorhus" 14808 + } 14809 + }, 14771 14810 "node_modules/estree-util-visit": { 14772 14811 "version": "1.2.1", 14773 14812 "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz", ··· 19583 19622 "node_modules/lodash": { 19584 19623 "version": "4.17.21", 19585 19624 "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", 19586 - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", 19587 - "dev": true 19625 + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" 19588 19626 }, 19589 19627 "node_modules/lodash.debounce": { 19590 19628 "version": "4.0.8", ··· 25197 25235 "engines": { 25198 25236 "node": ">=8.10.0" 25199 25237 } 25238 + }, 25239 + "node_modules/reading-time": { 25240 + "version": "1.5.0", 25241 + "resolved": "https://registry.npmjs.org/reading-time/-/reading-time-1.5.0.tgz", 25242 + "integrity": "sha512-onYyVhBNr4CmAxFsKS7bz+uTLRakypIe4R+5A824vBSkQy/hB3fZepoVEf8OVAxzLvK+H/jm9TzpI3ETSm64Kg==" 25200 25243 }, 25201 25244 "node_modules/recast": { 25202 25245 "version": "0.23.4", ··· 31742 31785 }, 31743 31786 "peerDependencies": { 31744 31787 "prettier": ">=1.0.0" 31788 + } 31789 + }, 31790 + "node_modules/remark-reading-time": { 31791 + "version": "2.0.1", 31792 + "resolved": "https://registry.npmjs.org/remark-reading-time/-/remark-reading-time-2.0.1.tgz", 31793 + "integrity": "sha512-fy4BKy9SRhtYbEHvp6AItbRTnrhiDGbqLQTSYVbQPGuRCncU1ubSsh9p/W5QZSxtYcUXv8KGL0xBgPLyNJA1xw==", 31794 + "dependencies": { 31795 + "estree-util-is-identifier-name": "^2.0.0", 31796 + "estree-util-value-to-estree": "^1.3.0", 31797 + "reading-time": "^1.3.0", 31798 + "unist-util-visit": "^3.1.0" 31799 + } 31800 + }, 31801 + "node_modules/remark-reading-time/node_modules/@types/unist": { 31802 + "version": "2.0.10", 31803 + "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.10.tgz", 31804 + "integrity": "sha512-IfYcSBWE3hLpBg8+X2SEa8LVkJdJEkT2Ese2aaLs3ptGdVtABxndrMaxuFlQ1qdFf9Q5rDvDpxI3WwgvKFAsQA==" 31805 + }, 31806 + "node_modules/remark-reading-time/node_modules/estree-util-is-identifier-name": { 31807 + "version": "2.1.0", 31808 + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz", 31809 + "integrity": "sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==", 31810 + "funding": { 31811 + "type": "opencollective", 31812 + "url": "https://opencollective.com/unified" 31813 + } 31814 + }, 31815 + "node_modules/remark-reading-time/node_modules/unist-util-is": { 31816 + "version": "5.2.1", 31817 + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", 31818 + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", 31819 + "dependencies": { 31820 + "@types/unist": "^2.0.0" 31821 + }, 31822 + "funding": { 31823 + "type": "opencollective", 31824 + "url": "https://opencollective.com/unified" 31825 + } 31826 + }, 31827 + "node_modules/remark-reading-time/node_modules/unist-util-visit": { 31828 + "version": "3.1.0", 31829 + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-3.1.0.tgz", 31830 + "integrity": "sha512-Szoh+R/Ll68QWAyQyZZpQzZQm2UPbxibDvaY8Xc9SUtYgPsDzx5AWSk++UUt2hJuow8mvwR+rG+LQLw+KsuAKA==", 31831 + "dependencies": { 31832 + "@types/unist": "^2.0.0", 31833 + "unist-util-is": "^5.0.0", 31834 + "unist-util-visit-parents": "^4.0.0" 31835 + }, 31836 + "funding": { 31837 + "type": "opencollective", 31838 + "url": "https://opencollective.com/unified" 31839 + } 31840 + }, 31841 + "node_modules/remark-reading-time/node_modules/unist-util-visit-parents": { 31842 + "version": "4.1.1", 31843 + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-4.1.1.tgz", 31844 + "integrity": "sha512-1xAFJXAKpnnJl8G7K5KgU7FY55y3GcLIXqkzUj5QF/QVP7biUm0K0O2oqVkYsdjzJKifYeWn9+o6piAK2hGSHw==", 31845 + "dependencies": { 31846 + "@types/unist": "^2.0.0", 31847 + "unist-util-is": "^5.0.0" 31848 + }, 31849 + "funding": { 31850 + "type": "opencollective", 31851 + "url": "https://opencollective.com/unified" 31745 31852 } 31746 31853 }, 31747 31854 "node_modules/remark-rehype": {
+5 -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", 20 21 "build": "cross-env NODE_NO_WARNINGS=1 next build", 21 22 "start": "cross-env NODE_NO_WARNINGS=1 next start", 22 - "deploy": "cross-env NEXT_STATIC_EXPORT=true npm run build", 23 + "deploy": "cross-env NEXT_PUBLIC_STATIC_EXPORT=true npm run build", 23 24 "lint:js": "eslint \"**/*.{js,mjs,ts,tsx}\" --cache --cache-strategy=content --cache-location=.eslintjscache", 24 25 "lint:md": "eslint \"**/*.md?(x)\" --cache --cache-strategy=content --cache-location=.eslintmdcache", 25 26 "lint:css": "stylelint \"**/*.css\" --allow-empty-input --cache --cache-strategy=content --cache-location=.stylelintcache", ··· 47 48 "@radix-ui/react-select": "^2.0.0", 48 49 "@radix-ui/react-tabs": "^1.0.4", 49 50 "@radix-ui/react-toast": "^1.1.5", 51 + "@savvywombat/tailwindcss-grid-areas": "~3.1.0", 50 52 "@sentry/nextjs": "~7.84.0", 51 53 "@types/node": "20.8.10", 52 54 "@vcarl/remark-headings": "~0.1.0", ··· 55 57 "classnames": "~2.3.2", 56 58 "cross-env": "7.0.3", 57 59 "feed": "~4.2.2", 60 + "github-slugger": "~2.0.0", 58 61 "glob": "~10.3.10", 59 62 "gray-matter": "~4.0.3", 60 63 "husky": "8.0.3", ··· 72 75 "rehype-autolink-headings": "~7.1.0", 73 76 "rehype-slug": "~6.0.0", 74 77 "remark-gfm": "~4.0.0", 78 + "remark-reading-time": "~2.0.1", 75 79 "semver": "~7.5.4", 76 80 "sharp": "0.32.6", 77 81 "shikiji": "~0.7.3",
+1 -11
pages/en/about/previous-releases.mdx
··· 18 18 19 19 ### Looking for latest release of a version branch? 20 20 21 - <section> 22 - <DownloadReleasesTable /> 23 - 24 - <small> 25 - [<a href="#backref-1">1</a>]: <code>NODE_MODULE_VERSION</code> refers to the ABI (application binary 26 - interface) version number of Node.js, used to determine which versions of 27 - Node.js compiled C++ add-on binaries can be loaded in to without needing to be 28 - re-compiled. It used to be stored as hex value in earlier versions, but is now 29 - represented as an integer. 30 - </small> 31 - </section> 21 + <DownloadReleasesTable />
+15 -13
providers/matterProvider.tsx
··· 3 3 import type { Heading } from '@vcarl/remark-headings'; 4 4 import { createContext } from 'react'; 5 5 import type { FC, PropsWithChildren } from 'react'; 6 + import type { ReadTimeResults } from 'reading-time'; 6 7 7 8 import type { LegacyFrontMatter } from '@/types'; 8 9 9 - type MatterContext = { matter: LegacyFrontMatter; headings: Heading[] }; 10 + type MatterContext = { 11 + frontmatter: LegacyFrontMatter; 12 + pathname: string; 13 + headings: Heading[]; 14 + readingTime: ReadTimeResults; 15 + filename: string; 16 + }; 10 17 11 18 export const MatterContext = createContext<MatterContext>({ 12 - matter: {}, 19 + frontmatter: {}, 20 + pathname: '', 13 21 headings: [], 22 + readingTime: { text: '', minutes: 0, time: 0, words: 0 }, 23 + filename: '', 14 24 }); 15 25 16 - type MatterProviderProps = PropsWithChildren<{ 17 - matter: LegacyFrontMatter; 18 - headings: Heading[]; 19 - }>; 26 + type MatterProviderProps = PropsWithChildren<MatterContext>; 20 27 21 28 export const MatterProvider: FC<MatterProviderProps> = ({ 22 - matter, 23 - headings, 24 29 children, 25 - }) => ( 26 - <MatterContext.Provider value={{ matter, headings }}> 27 - {children} 28 - </MatterContext.Provider> 29 - ); 30 + ...data 31 + }) => <MatterContext.Provider value={data}>{children}</MatterContext.Provider>;
+19
styles/new/base.css
··· 1 + * { 2 + @apply subpixel-antialiased; 3 + } 4 + 5 + html, 6 + body { 7 + @apply h-full 8 + w-full 9 + overflow-hidden; 10 + } 11 + 12 + body { 13 + @apply scroll-smooth 14 + bg-white 15 + font-open-sans 16 + text-neutral-950 17 + dark:bg-neutral-950 18 + dark:text-white; 19 + }
+1 -4
styles/new/index.css
··· 10 10 @import 'tailwindcss/components'; 11 11 @import 'tailwindcss/utilities'; 12 12 @import './mixins'; 13 + @import './base.css'; 13 14 @import './markdown.css'; 14 - 15 - * { 16 - @apply subpixel-antialiased; 17 - }
+31 -12
styles/new/markdown.css
··· 1 1 .mdxContent { 2 - h1 { 3 - @apply text-4xl; 2 + hr { 3 + @apply w-full 4 + border-t 5 + border-t-neutral-200 6 + bg-white 7 + dark:border-t-neutral-900 8 + dark:bg-neutral-950; 4 9 } 5 10 6 - h2 { 11 + h1 { 7 12 @apply text-3xl; 8 13 } 9 14 10 - h3 { 15 + h2 { 11 16 @apply text-2xl; 12 17 } 13 18 14 - h4 { 19 + h3 { 15 20 @apply text-xl; 16 21 } 17 22 18 - h5 { 23 + h4 { 19 24 @apply text-lg; 20 25 } 21 26 27 + h5, 22 28 h6, 23 29 strong { 24 30 @apply text-base; ··· 51 57 a, 52 58 a:link, 53 59 a:visited { 54 - @apply text-green-600 60 + @apply inline-block 61 + text-green-600 55 62 dark:text-green-400; 56 63 57 64 &:hover { ··· 62 69 63 70 ul { 64 71 @apply list-disc 65 - px-5 72 + pl-9 73 + pr-5 66 74 leading-6 67 75 text-neutral-900 68 76 dark:text-white; ··· 77 85 } 78 86 79 87 table { 80 - @apply w-full 88 + @apply mb-1 89 + w-full 81 90 border-separate 82 91 border-spacing-0 83 92 rounded ··· 97 106 py-2 98 107 text-neutral-900 99 108 dark:border-neutral-800 100 - dark:text-white; 109 + dark:text-white 110 + xs:block 111 + xs:border-l-0; 112 + 113 + > a { 114 + @apply pr-2; 115 + } 101 116 } 102 117 103 118 th { ··· 105 120 } 106 121 107 122 tr:last-child td { 108 - @apply border-b-0; 123 + @apply sm:border-b-0; 124 + 125 + &:last-child { 126 + @apply xs:border-b-0; 127 + } 109 128 } 110 129 111 130 td:first-child, 112 131 th:first-child { 113 - @apply border-l-0; 132 + @apply sm:border-l-0; 114 133 } 115 134 } 116 135 }
+5
styles/old/page-modules/download.css
··· 160 160 161 161 > thead { 162 162 font-weight: 600; 163 + 164 + th:last-child { 165 + text-align: left; 166 + padding-left: 1.5rem; 167 + } 163 168 } 164 169 165 170 > tbody {
+11 -8
tailwind.config.ts
··· 92 92 white: '#FFFFFF', 93 93 'white-opaque': 'rgba(255, 255, 255, 0.5)', 94 94 transparent: 'transparent', 95 + shadow: '#101828', 95 96 }, 96 97 fontSize: { 97 98 xs: ['0.75rem', '1rem'], ··· 117 118 'ibm-plex-mono': ['var(--font-ibm-plex-mono)'], 118 119 }, 119 120 extend: { 121 + screens: { xs: { max: '639px' } }, 120 122 backgroundImage: { 121 123 'gradient-radial': 'radial-gradient(var(--tw-gradient-stops))', 124 + 'gradient-subtle': 125 + 'linear-gradient(180deg, theme(colors.neutral.100 / 50%) 0%, theme(colors.neutral.100 / 0%) 48.32%)', 126 + 'gradient-subtle-dark': 127 + 'linear-gradient(180deg, theme(colors.neutral.900 / 50%) 0%, theme(colors.neutral.900 / 0%) 48.32%)', 122 128 }, 123 129 boxShadow: { 124 - xs: '0px 1px 2px 0px rgba(16, 24, 40, 0.05)', 125 - lg: '0px 4px 6px -2px rgba(16, 24, 40, 0.03), 0px 12px 16px -4px rgba(16, 24, 40, 0.08)', 126 - }, 127 - spacing: { 128 - '4.5': '1.125rem', 130 + xs: '0px 1px 2px 0px theme(colors.shadow / 5%)', 131 + lg: '0px 4px 6px -2px theme(colors.shadow / 3%), 0px 12px 16px -4px theme(colors.shadow / 8%)', 129 132 }, 130 - aria: { 131 - current: 'current="page"', 132 - }, 133 + spacing: { '4.5': '1.125rem' }, 134 + aria: { current: 'current="page"' }, 133 135 }, 134 136 }, 135 137 darkMode: ['class', '[data-theme="dark"]'], 138 + plugins: [require('@savvywombat/tailwindcss-grid-areas')], 136 139 } satisfies Config;
+4 -4
turbo.json
··· 7 7 "persistent": true, 8 8 "env": [ 9 9 "NEXT_PUBLIC_VERCEL_ENV", 10 - "NEXT_STATIC_EXPORT", 10 + "NEXT_PUBLIC_STATIC_EXPORT", 11 11 "NEXT_PUBLIC_BASE_URL", 12 12 "NEXT_PUBLIC_VERCEL_URL", 13 13 "NEXT_PUBLIC_DIST_URL", ··· 26 26 "outputs": [".next/**", "!.next/cache/**"], 27 27 "env": [ 28 28 "NEXT_PUBLIC_VERCEL_ENV", 29 - "NEXT_STATIC_EXPORT", 29 + "NEXT_PUBLIC_STATIC_EXPORT", 30 30 "NEXT_PUBLIC_BASE_URL", 31 31 "NEXT_PUBLIC_VERCEL_URL", 32 32 "NEXT_PUBLIC_DIST_URL", ··· 39 39 "persistent": true, 40 40 "env": [ 41 41 "NEXT_PUBLIC_VERCEL_ENV", 42 - "NEXT_STATIC_EXPORT", 42 + "NEXT_PUBLIC_STATIC_EXPORT", 43 43 "NEXT_PUBLIC_BASE_URL", 44 44 "NEXT_PUBLIC_VERCEL_URL", 45 45 "NEXT_PUBLIC_DIST_URL", ··· 58 58 "outputs": [".next/**", "!.next/cache/**"], 59 59 "env": [ 60 60 "NEXT_PUBLIC_VERCEL_ENV", 61 - "NEXT_STATIC_EXPORT", 61 + "NEXT_PUBLIC_STATIC_EXPORT", 62 62 "NEXT_PUBLIC_BASE_URL", 63 63 "NEXT_PUBLIC_VERCEL_URL", 64 64 "NEXT_PUBLIC_DIST_URL",
+7
types/i18n.ts
··· 1 + import type { JSXElementConstructor, ReactElement, ReactNode } from 'react'; 2 + 1 3 export interface LocaleConfig { 2 4 code: string; 3 5 localName: string; ··· 7 9 hrefLang: string; 8 10 enabled: boolean; 9 11 } 12 + 13 + export type FormattedMessage = 14 + | string 15 + | ReactElement<HTMLElement, string | JSXElementConstructor<HTMLElement>> 16 + | readonly ReactNode[];
+5 -10
types/navigation.ts
··· 1 - import type { useTranslations } from 'next-intl'; 2 - 3 1 export type NavigationKeys = 4 2 | 'about' 5 3 | 'download' ··· 10 8 | 'blog'; 11 9 12 10 export interface NavigationEntry { 13 - translationId: string; 14 - link: string; 11 + label?: string; 12 + link?: string; 15 13 items?: Record<string, NavigationEntry>; 16 14 } 17 15 18 - export interface MappedNavigationEntry { 19 - text: ReturnType<ReturnType<typeof useTranslations>['rich']>; 20 - link: string; 21 - key: string; 22 - level: number; 23 - items: MappedNavigationEntry[]; 16 + export interface SiteNavigation { 17 + topNavigation: Record<NavigationKeys, NavigationEntry>; 18 + sideNavigation: Record<NavigationKeys, NavigationEntry>; 24 19 }
+3
types/server.ts
··· 1 1 import type { Heading } from '@vcarl/remark-headings'; 2 + import type { ReadTimeResults } from 'reading-time'; 2 3 3 4 import type { LegacyFrontMatter } from './frontmatter'; 4 5 ··· 6 7 frontmatter: LegacyFrontMatter; 7 8 headings: Heading[]; 8 9 pathname: string; 10 + filename: string; 11 + readingTime: ReadTimeResults; 9 12 }
+11
util/gitHubUtils.ts
··· 1 + import GitHubSlugger from 'github-slugger'; 2 + 1 3 export const githubProfileAvatarUrl = (username: string): string => 2 4 `https://avatars.githubusercontent.com/${username}`; 5 + 6 + export const createGitHubSlug = () => { 7 + const githubSlugger = new GitHubSlugger(); 8 + 9 + return (text: string) => githubSlugger.slug(text); 10 + }; 11 + 12 + export const getGitHubEditPageUrl = (filename: string) => 13 + `https://github.com/nodejs/nodejs.org/blob/main/pages/en/${filename}`;