diff --git a/.editorconfig b/.editorconfig index e85c3fc5982f..c6c8b3621938 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,13 +1,9 @@ -# https://editorconfig.org/ - root = true [*] indent_style = space indent_size = 2 end_of_line = lf -insert_final_newline = true +charset = utf-8 trim_trailing_whitespace = true - -[*.svg] -insert_final_newline = false +insert_final_newline = true diff --git a/.eslintignore b/.eslintignore index 0a78c7ae867a..23d7ce3c80d8 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,4 +1,17 @@ -**/*.min.js -static/legacy/ -external/ -build/ +build +.next +external +styles +node_modules +public/en/user-survey-report +public/static/documents +public/static/legacy + +# These should be fixed in the future as the +# tests and scripts will be updated in this PR +tests + +# MDX Plugin enforces Prettier formatting which should +# be done in the future as we don't want to update the Markdown file +# contents right now +pages/**/*.md diff --git a/.eslintrc b/.eslintrc index a7d672df29d7..1314b286eeaf 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,51 +1,72 @@ { - "extends": [ - "eslint:recommended", - "standard", - "prettier" - ], - "plugins": [ - "prettier" - ], - "rules": { - "prettier/prettier": "error" - }, + "extends": ["eslint:recommended", "next"], "overrides": [ { - "files": [ - "**/*.md" - ], - "plugins": [ - "markdown" - ], - "processor": "markdown/markdown" + "files": ["**/*.{mjs,js,jsx,ts,tsx}"], + "extends": ["plugin:prettier/recommended"], + "env": { "node": true, "es6": true } + }, + { + "files": ["**/*.{ts,tsx}"], + "globals": { "globalThis": false } + }, + { + "files": ["**/*.tsx"], + "rules": { + "react/no-unused-prop-types": "off", + "react/require-default-props": "off", + "react/jsx-props-no-spreading": "off", + "react-hooks/rules-of-hooks": "error", + "react-hooks/exhaustive-deps": "warn", + "consistent-return": "off", + "react/function-component-definition": [ + "error", + { + "namedComponents": "arrow-function", + "unnamedComponents": "arrow-function" + } + ], + "react/jsx-filename-extension": [ + 2, + { "extensions": [".js", ".jsx", ".ts", ".tsx"] } + ] + } + }, + { + "files": ["**/*.{md,mdx}"], + "extends": ["plugin:mdx/recommended"], + "settings": { "mdx/code-blocks": false }, + "rules": { "react/jsx-no-undef": "off", "no-useless-escape": "off" } }, { "files": [ - "**/*.md/*.js" + "pages/*/about/*.{md,mdx}", + "pages/*/download/*.{md,mdx}", + "pages/*/get-involved/*.{md,mdx}", + "pages/*/docs/*.{md,mdx}", + "pages/*/*.{md,mdx}" ], - "parserOptions": { - "ecmaVersion": "latest" - }, + "settings": { "mdx/code-blocks": true } + }, + { + "files": ["pages/**/*.{md,mdx}/*.{js,jsx,cjs,mjs,ts,tsx}"], "rules": { - "eqeqeq": "off", - "n/no-deprecated-api": "off", - "n/handle-callback-err": "off", - "no-const-assign": "off", + "camelcase": "off", + "@typescript-eslint/no-unused-vars": "off", + "consistent-return": "off", + "func-names": "off", + "import/extensions": "off", + "import/no-extraneous-dependencies": "off", + "import/no-unresolved": "off", + "no-console": "off", + "no-empty": "off", + "no-restricted-globals": "off", + "no-restricted-syntax": "off", "no-undef": "off", + "no-underscore-dangle": "off", "no-unused-expressions": "off", "no-unused-vars": "off", - "node/handle-callback-err": "off", - "node/no-deprecated-api": "off", - "prefer-const": "off", - "prettier/prettier": [ - "error", - { - "singleQuote": true, - "trailingComma": "none" - } - ], - "semi": ["error", "always"] + "prefer-promise-reject-errors": "off" } } ] diff --git a/.github/ISSUE_TEMPLATE/01-bug-report.yml b/.github/ISSUE_TEMPLATE/01-bug-report.yml index 4296d9ab9c8c..d370614ef1c6 100644 --- a/.github/ISSUE_TEMPLATE/01-bug-report.yml +++ b/.github/ISSUE_TEMPLATE/01-bug-report.yml @@ -11,37 +11,36 @@ body: for us to fix it when you attach a screenshot as well. - type: input attributes: - label: "URL:" + label: 'URL:' description: The URL of the page you are reporting an issue on. placeholder: https://nodejs.org/en/ validations: required: true - type: input attributes: - label: "Browser Name:" - description: What kind of browser are you using? + label: 'Browser Name:' + description: What kind of browser are you using? placeholder: Chrome validations: required: true - type: input attributes: - label: "Browser Version:" + label: 'Browser Version:' description: What version of browser are you using? - placeholder: "103.0.5060.134" + placeholder: '103.0.5060.134' validations: required: true - type: input attributes: - label: "Operation System:" - description: - What kind of operation system are you using + label: 'Operation System:' + description: What kind of operation system are you using (Write it in full, with version number)? - placeholder: "Windows 10, 21H2, 19044.1826" + placeholder: 'Windows 10, 21H2, 19044.1826' validations: required: true - type: textarea attributes: - label: "How to reproduce the issue:" + label: 'How to reproduce the issue:' placeholder: | 1. What I did. 2. What I expected to happen. diff --git a/.github/ISSUE_TEMPLATE/02-feature-request.yml b/.github/ISSUE_TEMPLATE/02-feature-request.yml index 4ba32b7ac835..24dbbaf44bcd 100644 --- a/.github/ISSUE_TEMPLATE/02-feature-request.yml +++ b/.github/ISSUE_TEMPLATE/02-feature-request.yml @@ -12,7 +12,7 @@ body: so it might be a good idea to check out our plans there as well: https://github.com/nodejs/nodejs.dev/issues/. - type: textarea attributes: - label: "Enter your suggestions in details:" + label: 'Enter your suggestions in details:' placeholder: | 1. What I expected to happen. 2. Your reason (if possible, images or videos are welcome). diff --git a/.github/ISSUE_TEMPLATE/03-i18n.yml b/.github/ISSUE_TEMPLATE/03-i18n.yml index 6ad3d9daf672..e533f1750779 100644 --- a/.github/ISSUE_TEMPLATE/03-i18n.yml +++ b/.github/ISSUE_TEMPLATE/03-i18n.yml @@ -10,7 +10,7 @@ body: to create a new localization team. - type: textarea attributes: - label: "Enter your issue on localizations here:" + label: 'Enter your issue on localizations here:' placeholder: | 1. The name of the team (e.g: nodejs/node-cn). 2. Any problems to report or you want to create it? diff --git a/.github/dependabot.yml b/.github/dependabot.yml index 774051b2278c..c828ff0df135 100644 --- a/.github/dependabot.yml +++ b/.github/dependabot.yml @@ -1,12 +1,12 @@ version: 2 updates: - package-ecosystem: github-actions - directory: "/" + directory: '/' schedule: interval: weekly open-pull-requests-limit: 10 - package-ecosystem: npm - directory: "/" + directory: '/' schedule: interval: weekly open-pull-requests-limit: 10 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 5dada5c8f742..a9a1d9441b93 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,7 +22,7 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: "lts/*" + node-version-file: '.nvmrc' cache: npm - name: Install npm dependencies @@ -31,9 +31,9 @@ jobs: - name: Lint run: | echo "::add-matcher::.github/workflows/remark-lint-problem-matcher.json" - npm run test:lint + npm run lint - test: + build: name: Node on ${{ matrix.os }} runs-on: ${{ matrix.os }} @@ -49,28 +49,47 @@ jobs: - name: Set up Node.js uses: actions/setup-node@v3 with: - node-version: "lts/*" + node-version-file: '.nvmrc' cache: npm - - run: java -version - - - name: Install npm dependencies + - name: Install NPM dependencies run: npm ci - - name: Build - run: npm run build - - - name: Run unit tests - run: npm run test:unit + - name: Restore Next.js cache + uses: actions/cache/restore@v3 + with: + path: | + ${{ github.workspace }}/.next/cache + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}- - - name: Run HTML validator - run: npm run test:html + - name: Build Next.js + run: npm run build + env: + NODE_OPTIONS: '--max_old_space_size=4096' - - name: Run linkinator - uses: JustinBeckwith/linkinator-action@v1 + - name: Save Next.js cache + uses: actions/cache/save@v3 with: - linksToSkip: "^(?!http://localhost)" - paths: en - recurse: true - serverRoot: build - verbosity: error + path: | + ${{ github.workspace }}/.next/cache + key: ${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-${{ hashFiles('.next/cache/eslint') }} + + - name: Export Next.js + run: npm run export + + # We don't generate non-translated pages. So if a certain page on /en/ exists + # but not on /de/ or any other language, it will 404. This is handled on nginx level + # Prior to this migration Metalsmith would copy the English version of a page to all + # the non-translated pages. "Fooling" the 404 by basically adding i18n context with + # an untranslated page. This would be very exhaustive with Next.js on SCG mode + # but it's something we want to do once we decide upon using Next.js on SSR mode or + # if we decide upon using Vercel's infrastructure as generating a copy of every English page + # on the file system is very resource exhaustive. + # - name: Run linkinator + # uses: JustinBeckwith/linkinator-action@v1 + # with: + # linksToSkip: '^(?!http://localhost)' + # paths: en + # recurse: true + # serverRoot: build + # verbosity: error diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 93e877256c86..bbc767c9a9e4 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,4 +1,4 @@ -name: "CodeQL" +name: 'CodeQL' on: push: @@ -8,7 +8,7 @@ on: branches: - main schedule: - - cron: "0 0 * * 0" + - cron: '0 0 * * 0' workflow_dispatch: jobs: @@ -27,7 +27,7 @@ jobs: - name: Initialize CodeQL uses: github/codeql-action/init@v2 with: - languages: "javascript" + languages: 'javascript' - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@v2 diff --git a/.gitignore b/.gitignore index c648057343c3..873453a7e427 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,3 @@ -# Generated HTML and other static files -build/ # Commonly ignored Node.js files node_modules/ npm-debug.log @@ -10,7 +8,13 @@ npm-debug.log .AppleDouble .LSOverride -# Netlify -.netlify +# Next.js files +.next +build +public/sitemap.xml +public/en/feed/*.xml +pages/en/blog/year-[0-9][0-9][0-9][0-9].md -.cache/ +# ESLint Cache Files +.eslintjscache +.eslintmdcache diff --git a/.mailmap b/.mailmap deleted file mode 100644 index ce9ed4e2b3ee..000000000000 --- a/.mailmap +++ /dev/null @@ -1 +0,0 @@ -Mary Marchini diff --git a/.nvmrc b/.nvmrc new file mode 100644 index 000000000000..a77793ecc520 --- /dev/null +++ b/.nvmrc @@ -0,0 +1 @@ +lts/hydrogen diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 000000000000..23d7ce3c80d8 --- /dev/null +++ b/.prettierignore @@ -0,0 +1,17 @@ +build +.next +external +styles +node_modules +public/en/user-survey-report +public/static/documents +public/static/legacy + +# These should be fixed in the future as the +# tests and scripts will be updated in this PR +tests + +# MDX Plugin enforces Prettier formatting which should +# be done in the future as we don't want to update the Markdown file +# contents right now +pages/**/*.md diff --git a/.prettierrc b/.prettierrc new file mode 100644 index 000000000000..867a6097eeb5 --- /dev/null +++ b/.prettierrc @@ -0,0 +1,12 @@ +{ + "printWidth": 80, + "tabWidth": 2, + "useTabs": false, + "semi": true, + "singleQuote": true, + "jsxSingleQuote": false, + "trailingComma": "es5", + "bracketSpacing": true, + "bracketSameLine": false, + "arrowParens": "avoid" +} diff --git a/.prettierrc.json b/.prettierrc.json deleted file mode 100644 index 0fbddb05993d..000000000000 --- a/.prettierrc.json +++ /dev/null @@ -1,13 +0,0 @@ -{ - "overrides": [ - { - "files":[ - "**/*.js" - ], - "options": { - "singleQuote": true, - "trailingComma": "none" - } - } - ] -} diff --git a/.remarkignore b/.remarkignore deleted file mode 100644 index 2b569d27b58d..000000000000 --- a/.remarkignore +++ /dev/null @@ -1,4 +0,0 @@ -# We don't need to check all the md files under 'test/scripts' -# Because they are for test ONLY - -tests/scripts/ diff --git a/.remarkrc b/.remarkrc index 89bb6a54f34e..c7ef88977fc9 100644 --- a/.remarkrc +++ b/.remarkrc @@ -1,14 +1,38 @@ { "plugins": [ - "remark-frontmatter", "remark-preset-lint-node", - ["remark-lint-fenced-code-flag", false], - ["remark-lint-first-heading-level", false], - ["remark-lint-maximum-line-length", false], - ["remark-lint-no-file-name-articles", false], - ["remark-lint-no-literal-urls", false], - ["remark-lint-no-undefined-references", false], - ["remark-lint-prohibited-strings", false], - ["remark-preset-lint-node/remark-lint-nodejs-links.js", false] + "preset-prettier", + [ + "remark-lint-fenced-code-flag", + false + ], + [ + "remark-lint-first-heading-level", + false + ], + [ + "remark-lint-maximum-line-length", + false + ], + [ + "remark-lint-no-file-name-articles", + false + ], + [ + "remark-lint-no-literal-urls", + false + ], + [ + "remark-lint-no-undefined-references", + false + ], + [ + "remark-lint-prohibited-strings", + false + ], + [ + "remark-preset-lint-node/remark-lint-nodejs-links.js", + false + ] ] } diff --git a/.stylelintignore b/.stylelintignore index 5021b0283305..988c07b6516f 100644 --- a/.stylelintignore +++ b/.stylelintignore @@ -1,2 +1,2 @@ -/build/ -**/vendor/ +build +public diff --git a/.stylelintrc b/.stylelintrc index 7d578a7d42f5..a582d6bed2b5 100644 --- a/.stylelintrc +++ b/.stylelintrc @@ -1,12 +1,13 @@ { - "extends": [ - "stylelint-config-twbs-bootstrap" - ], + "extends": ["stylelint-config-recommended-scss"], + "plugins": ["stylelint-order", "stylelint-selector-bem-pattern"], "rules": { - "declaration-no-important": null, - "order/properties-order": null, - "selector-max-id": 1, - "selector-max-type": null, - "selector-no-qualifying-type": null + "order/properties-alphabetical-order": true, + "no-descending-specificity": null, + "scss/at-extend-no-missing-placeholder": null, + "selector-pseudo-class-no-unknown": [ + true, + { "ignorePseudoClasses": ["global"] } + ] } } diff --git a/CODEOWNERS b/CODEOWNERS index 4463b482983f..6bb1b99a2533 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -1,18 +1,19 @@ # Localization teams -/locale/ar/ @nodejs/nodejs-ar -/locale/ca/ # No Catalan team -/locale/de/ @nodejs/nodejs-de -/locale/es/ @nodejs/nodejs-es -/locale/fa/ @nodejs/nodejs-fa -/locale/fr/ @nodejs/nodejs-fr -/locale/gl/ # No Galacian team -/locale/it/ @nodejs/nodejs-it -/locale/ja/ @nodejs/nodejs-ja -/locale/ko/ @nodejs/nodejs-ko -/locale/pt-br/ @nodejs/nodejs-pt -/locale/ro/ @nodejs/nodejs-ro -/locale/ru/ @nodejs/nodejs-ru -/locale/tr/ @nodejs/nodejs-tr -/locale/uk/ @nodejs/nodejs-uk -/locale/zh-cn/ @nodejs/nodejs-cn -/locale/zh-tw/ @nodejs/nodejs-tw + +/pages/ar/ @nodejs/nodejs-ar +/pages/ca/ # No Catalan team +/pages/de/ @nodejs/nodejs-de +/pages/es/ @nodejs/nodejs-es +/pages/fa/ @nodejs/nodejs-fa +/pages/fr/ @nodejs/nodejs-fr +/pages/gl/ # No Galacian team +/pages/it/ @nodejs/nodejs-it +/pages/ja/ @nodejs/nodejs-ja +/pages/ko/ @nodejs/nodejs-ko +/pages/pt-br/ @nodejs/nodejs-pt +/pages/ro/ @nodejs/nodejs-ro +/pages/ru/ @nodejs/nodejs-ru +/pages/tr/ @nodejs/nodejs-tr +/pages/uk/ @nodejs/nodejs-uk +/pages/zh-cn/ @nodejs/nodejs-cn +/pages/zh-tw/ @nodejs/nodejs-tw diff --git a/COLLABORATOR_GUIDE.md b/COLLABORATOR_GUIDE.md index a88b692b9c26..602566ee507d 100644 --- a/COLLABORATOR_GUIDE.md +++ b/COLLABORATOR_GUIDE.md @@ -1,16 +1,14 @@ # Node.js Collaborator Guide -* [Issues and Pull Requests](#issues-and-pull-requests) -* [Accepting Modifications](#accepting-modifications) - * [Involving the Website Group](#involving-the-website-group) -* [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin-11) -* [Code of Conduct](#code-of-conduct) -* [Code editing](#code-editing) - * [Adding new pages](#adding-new-pages) - * [Create the page content](#create-the-page-content) - * [Update locale site.json to add link attributes](#update-locale-sitejson-to-add-link-attributes) - * [Update the layout to add a link](#update-the-layout-to-add-a-link) - * [Translating pages](#translating-pages) +- [Issues and Pull Requests](#issues-and-pull-requests) +- [Accepting Modifications](#accepting-modifications) + - [Involving the Website Group](#involving-the-website-group) +- [Developer's Certificate of Origin 1.1](#developers-certificate-of-origin-11) +- [Code of Conduct](#code-of-conduct) +- [Code editing](#code-editing) + - [Adding new pages](#adding-new-pages) + - [Create the page content](#create-the-page-content) + - [Translating pages](#translating-pages) This document contains information for Collaborators of the Node.js website project regarding maintaining the code, documentation and issues. @@ -70,7 +68,7 @@ lack of consensus may indicate the need to elevate discussion to the Website Group for resolution (see below). All bugfixes require a test case which demonstrates the defect. The -test should *fail* before the change, and *pass* after the change. +test should _fail_ before the change, and _pass_ after the change. All pull requests that modify executable code should be subjected to continuous integration tests on the @@ -82,9 +80,9 @@ Collaborators may opt to elevate pull requests or issues to the group for discussion by mentioning `@nodejs/website`. This should be done where a pull request: -* has a significant impact on the codebase, -* is inherently controversial; or -* has failed to reach consensus amongst the Collaborators who are +- has a significant impact on the codebase, +- is inherently controversial; or +- has failed to reach consensus amongst the Collaborators who are actively participating in the discussion. The Website group should serve as the final arbiter where required. @@ -93,11 +91,11 @@ The Website group should serve as the final arbiter where required. By making a contribution to this project, I certify that: -* (a) The contribution was created in whole or in part by me and I +- (a) The contribution was created in whole or in part by me and I have the right to submit it under the open source license indicated in the file; or -* (b) The contribution is based upon previous work that, to the best +- (b) The contribution is based upon previous work that, to the best of my knowledge, is covered under an appropriate open source license and I have the right under that license to submit that work with modifications, whether created in whole or in part @@ -105,11 +103,11 @@ By making a contribution to this project, I certify that: permitted to submit under a different license), as indicated in the file; or -* (c) The contribution was provided directly to me by some other +- (c) The contribution was provided directly to me by some other person who certified (a), (b) or (c) and I have not modified it. -* (d) I understand and agree that this project and the contribution +- (d) I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with @@ -120,35 +118,35 @@ By making a contribution to this project, I certify that: This Code of Conduct is adapted from [Rust's wonderful CoC](https://github.com/rust-lang/rust/wiki/Note-development-policy#conduct). -* We are committed to providing a friendly, safe and welcoming +- We are committed to providing a friendly, safe and welcoming environment for all, regardless of gender, sexual orientation, disability, ethnicity, religion, or similar personal characteristic. -* Please avoid using overtly sexual nicknames or other nicknames that +- Please avoid using overtly sexual nicknames or other nicknames that might detract from a friendly, safe and welcoming environment for all. -* Please be kind and courteous. There's no need to be mean or rude. -* Respect that people have differences of opinion and that every +- Please be kind and courteous. There's no need to be mean or rude. +- Respect that people have differences of opinion and that every design or implementation choice carries a trade-off and numerous costs. There is seldom a right answer. -* Please keep unstructured critique to a minimum. If you have solid +- Please keep unstructured critique to a minimum. If you have solid ideas you want to experiment with, make a fork and see how it works. -* We will exclude you from interaction if you insult, demean or harass +- We will exclude you from interaction if you insult, demean or harass anyone. That is not welcome behavior. We interpret the term "harassment" as including the definition in the [Citizen Code of Conduct](http://citizencodeofconduct.org/); if you have any lack of clarity about what might be included in that concept, please read their definition. In particular, we don't tolerate behavior that excludes people in socially marginalized groups. -* Private harassment is also unacceptable. No matter who you are, if +- Private harassment is also unacceptable. No matter who you are, if you feel you have been or are being harassed or made uncomfortable by a community member, please contact one of the channel ops or any of the TC members immediately with a capture (log, photo, email) of the harassment if possible. Whether you're a regular contributor or a newcomer, we care about making this community a safe place for you and we've got your back. -* Likewise any spamming, trolling, flaming, baiting or other +- Likewise any spamming, trolling, flaming, baiting or other attention-stealing behavior is not welcome. -* Avoid the use of personal pronouns in code comments or +- Avoid the use of personal pronouns in code comments or documentation. There is no need to address persons when explaining code (e.g. "When the developer") @@ -157,12 +155,11 @@ CoC](https://github.com/rust-lang/rust/wiki/Note-development-policy#conduct). ### Adding new pages 1. Create new page content including the layout, title and copy. -2. Update `/locale/en/site.json` to provide page link attributes. -3. Update the relevant `/layout` to add a link to the new page. +2. Update the relevant `/layout` to add a link to the new page. #### Create the page content -Create a new markdown file in `/local/en`. As specified in the +Create a new markdown file in `/pages/en`. As specified in the [README.md](./README.md#layout), initial development happens in English. At the top of the markdown file, set a page the title and layout. @@ -176,27 +173,6 @@ layout: contribute.hbs [Event copy goes here] ``` -#### Update locale site.json to add link attributes - -Open `local/en/site.json` and find the appropriate page structure. -Add a new object defining the link attributes. - -```json -"event": { - "link": "get-involved/events", - "text": "Events" -} -``` - -#### Update the layout to add a link - -Using the example layout, open `/layouts/contribute.hbs` and add your new -link to the markup. It's essential to update the handlebars paths to site.json. - -```handlebars -{{site.locale}}/{{site.getinvolved.events.link}} -``` - ### Translating pages See [TRANSLATION.md](./TRANSLATION.md) for the website translation policy. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6c1fa597134e..6c6e34641638 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -8,8 +8,8 @@ expectations the Node Foundation requires of its contributors. ## Vocabulary -* A **Contributor** is any individual creating or commenting on an issue or pull request. -* A **Collaborator** is a subset of contributors who have been given write access to the repository. +- A **Contributor** is any individual creating or commenting on an issue or pull request. +- A **Collaborator** is a subset of contributors who have been given write access to the repository. ## Logging Issues diff --git a/README.md b/README.md index de55448c67f5..cb91dbaa2402 100644 --- a/README.md +++ b/README.md @@ -23,13 +23,13 @@ In both cases the workflow is different, please check how it is done in each cas Please contribute! There are plenty of [good first issues](https://github.com/nodejs/nodejs.org/labels/good%20first%20issue) to work on. To get started, you have to [fork](https://github.com/nodejs/nodejs.org/fork) this repo to your own GitHub account first. Then open up a terminal on your machine and enter the following commands: ```bash -git clone https://github.com//nodejs.org.git +git clone https://github.com/{your username}/nodejs.org cd nodejs.org -npm install -npm start +npm ci +npm run serve ``` -This will start the development server on `http://localhost:8080/en/`. This page should reload automatically when you make changes to the code, but no code is perfect, so sometimes you may need to restart it. :) +This will start the development server on `http://localhost:3000/en/`. This page should reload automatically when you make changes to the code, but no code is perfect, so sometimes you may need to restart it. :) If you want to submit a new feature or a bugfix, the best way is to create the changes in a separate branch, e.g.: `git checkout -b feature/mycoolfeature`. This will make it easier for you to submit a pull request and get your feature merged. @@ -45,40 +45,35 @@ To help with localization, please read the [TRANSLATION](TRANSLATION.md) guide. ## Layout -* Page templates are in `/layouts` -* Global styles are in `/layouts/css` -* Global static files are in `/static` -* All content is in `/locale` - * Initial development usually happens in English: `/locale/en` - * `/locale/{{locale}}/site.json` is where global localization information lives. - * All content is in Markdown and is per locale. - * The top of each Markdown file is a block of YAML for page specific localization information that is passed to various templates. - * The bulk of the Markdown content for each page is referenced as `{{{content}}}` in the corresponding template. +- Page templates are in `/layouts` +- Global styles are in `/layouts/css` +- Global static files are in `/static` +- All content is in `/pages` + - Initial development usually happens in English: `/pages/en` + - `/i18n/locales/{{locale}}.json` is where global localization information lives. + - All content is in Markdown and is per locale. + - The top of each Markdown file is a block of YAML for page specific localization information that is passed to various templates. + - The bulk of the Markdown content for each page is referenced as `{{{content}}}` in the corresponding template. ## Serve/Build Options -* `DEFAULT_LOCALE={{locale}} node build.js` builds all the translated files present in the locale folder (will display 404 status code if file is not present), the static/css folder for all the Sass files, as well as copy the rest of the static assets to their subfolder in the build directory. -* `DEFAULT_LOCALE={{locale}} node build.js --preserveLocale` the same as `node build.js` but it will add the pages present in the English locale that are missing instead of throwing 404 status code. -* `DEFAULT_LOCALE={{locale}} npm run serve` builds only the files present in the specified locale folder (will display 404 status code if file is not present), then start the default website (`http://localhost:${port}/${mainLocale}`). Here `{port}` is 8080, `{mainLocale}` is `en` or the first specified language. -* `DEFAULT_LOCALE={{locale}} npm run serve -- --preserveLocale` the same as `npm run serve ` but it will add the pages present in the English locale that are missing. -* `npm run serve` builds all the current languages and returns 404 when a file is not present in the current locale, then start the default website (`http://localhost:${port}/${mainLocale}`). Here `{port}` is 8080, `{mainLocale}` is `en` in default. -* `npm run serve -- --preserveLocale` the same as `npm run serve` but it will add the pages present in the English locale that are missing instead of throwing 404 status code. +- `npm run serve` runs Next.js's Local Development Server, listening by default on `http://localhost:3000/`. +- `npm run build` builds the Application on Production mode. The output is by default within `.next` folder. +- `npm run export` exports the website from the `.next` into a fully static website. The output is by default within `build` folder. + - This is what it's used to deploy the website on our current Node.js servers. +- `npm run start` starts a web server running serving the built content from `npm run build` -## Test Options +## Other CLI options -Before submitting, you must pass all the unit tests and syntax checks by running the two commands below: +We also offer other commands that offer you assistance during your local development -* `npm-run-all test:lint test:unit` run all the unit test cases in `tests` folder, as well as check syntax with eslint. -* `npm-run-all --parallel test:lint:*` run all the syntax checks for `js`, `md` and other related files. - -There're also two syntax check commands for you: -* `npm run test:lint:js -- --fix` try to automatically fix some formations for all the js files. -* `npm run test:lint:stylelint -- --fix` try to automatically fix some formations for all the css/scss files. - -## Notice - -* Multiple locales can be built by using comma-separated values in the `DEFAULT_LOCALE` variable: `DEFAULT_LOCALE=en,es,it`. -* For other options, see `package.json`. +- `npm run lint` runs the linter for all the js files. + - `npm run lint:fix` attempts to fix any linting errors +- `npm run prettier` runs the prettier for all the js files. + - `npm run prettier:fix` attempts to fix any style errors +- `npm run format` formats and fixes the whole codebase +- `npm run scripts:release-post` generates a release post for the current release + - **Usage:** `npm run scripts:release-post -- --version=vXX.X.X --force` ## Deployment @@ -91,5 +86,5 @@ The Website Working Group is primarily concerned with the code and overall struc The content of the website comes from a variety of working groups (Evangelism, Core, i18n, etc). The Website WG defers to these WGs on matters of content and routinely adds collaborators from these working groups as they add and improve content on the website. In other words, the Website WG is not -an *editorial* Working Group except when no other Working Group has taken responsibility for a +an _editorial_ Working Group except when no other Working Group has taken responsibility for a content area. diff --git a/TRANSLATION.md b/TRANSLATION.md index 7007778270e0..1cdbc9b5a722 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -25,40 +25,40 @@ An existing localization group is not required to start translation. You can con Contact your appropriate localization group, and discuss with them the best possible way to contribute. A list of the localization groups can be found below. -* [`nodejs-ar`](https://github.com/nodejs/nodejs-ar) Arabic Community -* [`nodejs-bg`](https://github.com/nodejs/nodejs-bg) Bulgarian Community -* [`nodejs-bn`](https://github.com/nodejs/nodejs-bn) Bengali Community -* [`nodejs-zh-CN`](https://github.com/nodejs/nodejs-zh-CN) Chinese Community -* [`nodejs-cs`](https://github.com/nodejs/nodejs-cs) Czech Community -* [`nodejs-da`](https://github.com/nodejs/nodejs-da) Danish Community -* [`nodejs-de`](https://github.com/nodejs/nodejs-de) German Community -* [`nodejs-el`](https://github.com/nodejs/nodejs-el) Greek Community -* [`nodejs-es`](https://github.com/nodejs/nodejs-es) Spanish Community -* [`nodejs-fa`](https://github.com/nodejs/nodejs-fa) Persian Community -* [`nodejs-fi`](https://github.com/nodejs/nodejs-fi) Finnish Community -* [`nodejs-fr`](https://github.com/nodejs/nodejs-fr) French Community -* [`nodejs-he`](https://github.com/nodejs/nodejs-he) Hebrew Community -* [`nodejs-hi`](https://github.com/nodejs/nodejs-hi) Hindi Community -* [`nodejs-hu`](https://github.com/nodejs/nodejs-hu) Hungarian Community -* [`nodejs-id`](https://github.com/nodejs/nodejs-id) Indonesian Community -* [`nodejs-it`](https://github.com/nodejs/nodejs-it) Italian Community -* [`nodejs-ja`](https://github.com/nodejs/nodejs-ja) Japanese Community -* [`nodejs-ka`](https://github.com/nodejs/nodejs-ka) Georgian Community -* [`nodejs-ko`](https://github.com/nodejs/nodejs-ko) Korean Community -* [`nodejs-mk`](https://github.com/nodejs/nodejs-mk) Macedonian Community -* [`nodejs-ms`](https://github.com/nodejs/nodejs-ms) Malaysian Community -* [`nodejs-nl`](https://github.com/nodejs/nodejs-nl) Dutch Community -* [`nodejs-no`](https://github.com/nodejs/nodejs-no) Norwegian Community -* [`nodejs-pl`](https://github.com/nodejs/nodejs-pl) Polish Community -* [`nodejs-pt`](https://github.com/nodejs/nodejs-pt) Portuguese Community -* [`nodejs-ro`](https://github.com/nodejs/nodejs-ro) Romanian Community -* [`nodejs-ru`](https://github.com/nodejs/nodejs-ru) Russian Community -* [`nodejs-sv`](https://github.com/nodejs/nodejs-sv) Swedish Community -* [`nodejs-ta`](https://github.com/nodejs/nodejs-ta) Tamil Community -* [`nodejs-tr`](https://github.com/nodejs/nodejs-tr) Turkish Community -* [`nodejs-zh-TW`](https://github.com/nodejs/nodejs-zh-TW) Taiwanese Community -* [`nodejs-uk`](https://github.com/nodejs/nodejs-uk) Ukrainian Community -* [`nodejs-vi`](https://github.com/nodejs/nodejs-vi) Vietnamese Community +- [`nodejs-ar`](https://github.com/nodejs/nodejs-ar) Arabic Community +- [`nodejs-bg`](https://github.com/nodejs/nodejs-bg) Bulgarian Community +- [`nodejs-bn`](https://github.com/nodejs/nodejs-bn) Bengali Community +- [`nodejs-zh-CN`](https://github.com/nodejs/nodejs-zh-CN) Chinese Community +- [`nodejs-cs`](https://github.com/nodejs/nodejs-cs) Czech Community +- [`nodejs-da`](https://github.com/nodejs/nodejs-da) Danish Community +- [`nodejs-de`](https://github.com/nodejs/nodejs-de) German Community +- [`nodejs-el`](https://github.com/nodejs/nodejs-el) Greek Community +- [`nodejs-es`](https://github.com/nodejs/nodejs-es) Spanish Community +- [`nodejs-fa`](https://github.com/nodejs/nodejs-fa) Persian Community +- [`nodejs-fi`](https://github.com/nodejs/nodejs-fi) Finnish Community +- [`nodejs-fr`](https://github.com/nodejs/nodejs-fr) French Community +- [`nodejs-he`](https://github.com/nodejs/nodejs-he) Hebrew Community +- [`nodejs-hi`](https://github.com/nodejs/nodejs-hi) Hindi Community +- [`nodejs-hu`](https://github.com/nodejs/nodejs-hu) Hungarian Community +- [`nodejs-id`](https://github.com/nodejs/nodejs-id) Indonesian Community +- [`nodejs-it`](https://github.com/nodejs/nodejs-it) Italian Community +- [`nodejs-ja`](https://github.com/nodejs/nodejs-ja) Japanese Community +- [`nodejs-ka`](https://github.com/nodejs/nodejs-ka) Georgian Community +- [`nodejs-ko`](https://github.com/nodejs/nodejs-ko) Korean Community +- [`nodejs-mk`](https://github.com/nodejs/nodejs-mk) Macedonian Community +- [`nodejs-ms`](https://github.com/nodejs/nodejs-ms) Malaysian Community +- [`nodejs-nl`](https://github.com/nodejs/nodejs-nl) Dutch Community +- [`nodejs-no`](https://github.com/nodejs/nodejs-no) Norwegian Community +- [`nodejs-pl`](https://github.com/nodejs/nodejs-pl) Polish Community +- [`nodejs-pt`](https://github.com/nodejs/nodejs-pt) Portuguese Community +- [`nodejs-ro`](https://github.com/nodejs/nodejs-ro) Romanian Community +- [`nodejs-ru`](https://github.com/nodejs/nodejs-ru) Russian Community +- [`nodejs-sv`](https://github.com/nodejs/nodejs-sv) Swedish Community +- [`nodejs-ta`](https://github.com/nodejs/nodejs-ta) Tamil Community +- [`nodejs-tr`](https://github.com/nodejs/nodejs-tr) Turkish Community +- [`nodejs-zh-TW`](https://github.com/nodejs/nodejs-zh-TW) Taiwanese Community +- [`nodejs-uk`](https://github.com/nodejs/nodejs-uk) Ukrainian Community +- [`nodejs-vi`](https://github.com/nodejs/nodejs-vi) Vietnamese Community ### Group for my locale does not exist @@ -73,4 +73,4 @@ If you can't find group for your locale: If you find the group for your locale is archived: 1. Try to contact members of the group by creating a [new issue](https://github.com/nodejs/nodejs.org/issues/new?template=03-i18n.md) in this repo. Include a mention of the group so members get notified of the issue. -2. If there is no response from members in 7 days and if you have already done 1000 strings or more on Crowdin for your locale, open an issue in https://github.com/nodejs/admin requesting the repository be unarchived. +2. If there is no response from members in 7 days and if you have already done 1000 strings or more on Crowdin for your locale, open an issue in requesting the repository be unarchived. diff --git a/build.js b/build.js deleted file mode 100755 index eba639e7beb6..000000000000 --- a/build.js +++ /dev/null @@ -1,350 +0,0 @@ -#! /usr/bin/env node - -'use strict'; - -// BUILD.JS: This file is responsible for building static HTML pages - -const fs = require('fs'); -const gracefulFs = require('graceful-fs'); - -// This is needed at least on Windows to prevent the `EMFILE: too many open files` error -// https://github.com/isaacs/node-graceful-fs#global-patching -gracefulFs.gracefulify(fs); - -const path = require('path'); -const Metalsmith = require('metalsmith'); -const collections = require('metalsmith-collections'); -const feed = require('metalsmith-feed'); -const layouts = require('metalsmith-layouts'); -const markdown = require('@metalsmith/markdown'); -const permalinks = require('@metalsmith/permalinks'); -const pagination = require('metalsmith-yearly-pagination'); -const defaultsDeep = require('lodash.defaultsdeep'); -const autoprefixer = require('autoprefixer'); -const { marked } = require('marked'); -const postcss = require('postcss'); -const sass = require('sass'); -const junk = require('junk'); -const semver = require('semver'); -const replace = require('metalsmith-one-replace'); -const fsExtra = require('fs-extra'); - -const githubLinks = require('./scripts/plugins/githubLinks'); -const navigation = require('./scripts/plugins/navigation'); -const anchorMarkdownHeadings = require('./scripts/plugins/anchor-markdown-headings'); -const loadVersions = require('./scripts/load-versions'); -const latestVersion = require('./scripts/helpers/latestversion'); -const withPreserveLocale = require('./scripts/plugins/withPreserveLocale'); -const scriptReg = require('./scripts/plugins/scriptReg'); -const hbsReg = require('./scripts/plugins/hbsReg'); - -// Set the default language, also functions as a fallback for properties which -// are not defined in the given language. -const DEFAULT_LANG = 'en'; - -// The history links of nodejs versions at doc/index.md -const nodejsVersionsContent = fs - .readFileSync('./source/nodejsVersions.md') - .toString(); - -// Set up the Markdown renderer that we'll use for our Metalsmith build process. -const renderer = new marked.Renderer(); -renderer.heading = anchorMarkdownHeadings; -const markedOptions = { - renderer -}; - -// We are setting the output from `latestVersion` module here for future use. -// available props `latestVersionInfo` are `current` and `lts` -let latestVersionInfo = {}; - -// This function imports a given language file and uses the default language set -// in DEFAULT_LANG as a fallback to prevent any strings that aren't filled out -// from appearing as blank. -function i18nJSON(lang) { - const defaultJSON = require(`./locale/${DEFAULT_LANG}/site.json`); - const templateJSON = require(`./locale/${lang}/site.json`); - - return defaultsDeep({}, templateJSON, defaultJSON); -} - -// This function imports language file for each given locale in array 'localesList' -// and based on it generating locales data, which includes full language name, english language name, locale and link -function generateLocalesData(localesList) { - return localesList.map((localeEl) => { - const { - language, - languageEnglishVersion, - locale, - url - } = require(`./locale/${localeEl}/site.json`); - return { language, locale, url, languageEnglishVersion }; - }); -} - -// This is the function where the actual magic happens. This contains the main -// Metalsmith build cycle used for building a locale subsite, such as the -// english one. -function buildLocale(source, locale, opts) { - console.log(`[metalsmith] build/${locale} started`); - const labelForBuild = `[metalsmith] build/${locale} finished`; - console.time(labelForBuild); - const metalsmith = Metalsmith(__dirname); - metalsmith - // Sets global metadata imported from the locale's respective site.json. - .metadata({ - site: i18nJSON(locale), - project: source.project, - locales: opts.localesData - }) - // Sets the build source as the locale folder. - .source(path.join(__dirname, 'locale', locale)) - // site.json files aren't needed in the output dir - .ignore('site.json') - .use(withPreserveLocale(opts && opts.preserveLocale)) - // Extracts the main menu and sub-menu links form locale's site.json and - // adds them to the metadata. This data is used in the navigation template - .use(navigation(source.project.latestVersions)) - // Defines the blog post/guide collections used to internally group them for - // easier future handling and feed generation. - .use( - collections({ - blog: { - pattern: 'blog/**/*.md', - sortBy: 'date', - reverse: true, - refer: false - }, - blogReleases: { - pattern: 'blog/release/*.md', - sortBy: 'date', - reverse: true, - refer: false - }, - blogVulnerability: { - pattern: 'blog/vulnerability/*.md', - sortBy: 'date', - reverse: true, - refer: false - }, - knowledgeBase: { - pattern: 'knowledge/**/*.md', - refer: false - }, - guides: { - pattern: 'docs/guides/!(index).md' - } - }) - ) - .use( - pagination({ - path: 'blog/year', - iteratee: (post, idx) => ({ - post - }) - }) - ) - .use( - replace({ - actions: [ - { - type: 'var', - varValues: { - currentVersion: `latest-${latestVersionInfo.lts.nodeMajor}`, - nodeVersionLinks: nodejsVersionsContent - } - } - ] - }) - ) - .use(markdown(markedOptions)) - // Set pretty permalinks, we don't want .html suffixes everywhere. - .use( - permalinks({ - relative: false - }) - ) - // Generates the feed XML files from their respective collections which were - // defined earlier on. - .use( - feed({ - collection: 'blog', - destination: 'feed/blog.xml', - title: 'Node.js Blog' - }) - ) - .use( - feed({ - collection: 'blogReleases', - destination: 'feed/releases.xml', - title: 'Node.js Blog: Releases' - }) - ) - .use( - feed({ - collection: 'blogVulnerability', - destination: 'feed/vulnerability.xml', - title: 'Node.js Blog: Vulnerability Reports' - }) - ) - // Finally, this compiles the rest of the layouts present in ./layouts. - // They're language-agnostic, but have to be regenerated for every locale - // anyways. - .use(hbsReg()) - .use(scriptReg()) - .use(layouts()) - .use(githubLinks({ locale, site: i18nJSON(locale) })) - // Pipes the generated files into their respective subdirectory in the build - // directory. - .destination(path.join(__dirname, 'build', locale)) - // This actually executes the build and stops the internal timer after - // completion. - .build((err) => { - if (err) { - throw err; - } - console.timeEnd(labelForBuild); - }); -} - -// This function builds the static/css folder for all the Sass files. -async function buildCSS() { - console.log('[sass] static/css started'); - const labelForBuild = '[sass] static/css finished'; - console.time(labelForBuild); - - const src = path.join(__dirname, 'layouts/css/styles.scss'); - const sassOpts = { - outputStyle: - process.env.NODE_ENV !== 'development' ? 'compressed' : 'expanded' - }; - - const resultPromise = sass.compileAsync(src, sassOpts); - - const dest = path.join(__dirname, 'build/static/css/styles.css'); - - await fsExtra.promises.mkdir(path.join(__dirname, 'build/static/css'), { - recursive: true - }); - - const result = await resultPromise; - - postcss([autoprefixer]) - .process(result.css, { from: src }) - .then(async (res) => { - res.warnings().forEach((warn) => { - console.warn(warn.toString()); - }); - - await fsExtra.writeFile(dest, res.css); - console.timeEnd(labelForBuild); - }); -} - -// This function copies the rest of the static assets to their subfolder in the -// build directory. -async function copyStatic() { - console.log('[fsExtra] copy/static started'); - const labelForBuild = '[fsExtra] copy/static finished'; - console.time(labelForBuild); - - await fsExtra.promises.mkdir(path.join(__dirname, 'build/static/js'), { - recursive: true - }); - - await Promise.all([ - fsExtra.copy( - path.join(__dirname, 'static'), - path.join(__dirname, 'build/static'), - { overwrite: true, recursive: true } - ), - - fsExtra.copy( - path.join( - __dirname, - 'node_modules/jquery.fancytable/dist/fancyTable.min.js' - ), - path.join(__dirname, 'build/static/js/fancyTable.min.js'), - { overwrite: true } - ), - - fsExtra.copy( - path.join(__dirname, 'node_modules/jquery/dist/jquery.min.js'), - path.join(__dirname, 'build/static/js/jquery.min.js'), - { overwrite: true } - ) - ]); - - console.timeEnd(labelForBuild); -} - -function getSource(callback) { - // Loads all node/io.js versions. - loadVersions((err, versions) => { - latestVersionInfo = { - current: latestVersion.current(versions), - lts: latestVersion.lts(versions) - }; - const source = { - project: { - versions, - latestVersions: latestVersionInfo - } - }; - if ( - semver.gt( - source.project.latestVersions.lts.node, - source.project.latestVersions.current.node - ) - ) { - // If LTS is higher than Current hide it from the main page - source.project.latestVersions.hideCurrent = true; - } - - callback(err, source); - }); -} - -// This is where the build is orchestrated from, as indicated by the function -// name. It brings together all build steps and dependencies and executes them. -async function fullBuild(opts) { - const { selectedLocales, preserveLocale } = opts; - getSource(async (err, source) => { - if (err) { - throw err; - } - const locales = await fsExtra.promises.readdir( - path.join(__dirname, 'locale') - ); - - const filteredLocales = locales.filter( - (file) => - junk.not(file) && - (selectedLocales ? selectedLocales.includes(file) : true) - ); - const localesData = generateLocalesData(filteredLocales); - filteredLocales.forEach((locale) => { - buildLocale(source, locale, { preserveLocale, localesData }); - }); - }); -} - -// Starts the build if the file was executed from the command line -if (require.main === module) { - const preserveLocale = process.argv.includes('--preserveLocale'); - const selectedLocales = process.env.DEFAULT_LOCALE - ? process.env.DEFAULT_LOCALE.toLowerCase().split(',') - : process.env.DEFAULT_LOCALE; - // Copy static files - copyStatic(); - // Build CSS - buildCSS(); - fullBuild({ selectedLocales, preserveLocale }); -} - -exports.getSource = getSource; -exports.fullBuild = fullBuild; -exports.buildCSS = buildCSS; -exports.buildLocale = buildLocale; -exports.copyStatic = copyStatic; -exports.generateLocalesData = generateLocalesData; diff --git a/components/AnchoredHeading.tsx b/components/AnchoredHeading.tsx new file mode 100644 index 000000000000..1eef61371920 --- /dev/null +++ b/components/AnchoredHeading.tsx @@ -0,0 +1,29 @@ +import type { PropsWithChildren } from 'react'; + +type HeadingLevel = 1 | 2 | 3 | 4 | 5 | 6; + +type AnchorHeadingProps = PropsWithChildren<{ + level: HeadingLevel; + id?: string; +}>; + +const AnchoredHeading = ({ children, level, id }: AnchorHeadingProps) => { + const HeadingLevelTag = `h${level}` as any; + + // This regex replacement is used for comments within the heading + const sanitizedId = id?.replace(/---(.+)---(.*)/, (_, f) => f); + + return ( + + {children} + + + ); +}; + +export default AnchoredHeading; diff --git a/components/Docs/NodeApiVersionLinks.tsx b/components/Docs/NodeApiVersionLinks.tsx new file mode 100644 index 000000000000..af61b66803a0 --- /dev/null +++ b/components/Docs/NodeApiVersionLinks.tsx @@ -0,0 +1,64 @@ +import Link from 'next/link'; + +// Note.: This is a temporary Component used only until the transition to `nodejs/nodejs.dev` content is done +const NodeApiVersionLinks = () => ( +
    +
  • + Node.js 18.x +
  • +
  • + Node.js 17.x +
  • +
  • + Node.js 16.x +
  • +
  • + Node.js 15.x +
  • +
  • + Node.js 14.x +
  • +
  • + Node.js 13.x +
  • +
  • + Node.js 12.x +
  • +
  • + Node.js 11.x +
  • +
  • + Node.js 10.x +
  • +
  • + Node.js 9.x +
  • +
  • + Node.js 8.x +
  • +
  • + Node.js 7.x +
  • +
  • + Node.js 6.x +
  • +
  • + Node.js 5.x +
  • +
  • + Node.js 4.x +
  • +
  • + + Node.js 0.12.x + +
  • +
  • + + Node.js 0.10.x + +
  • +
+); + +export default NodeApiVersionLinks; diff --git a/components/Downloads/DownloadList.tsx b/components/Downloads/DownloadList.tsx new file mode 100644 index 000000000000..abaedbaab34a --- /dev/null +++ b/components/Downloads/DownloadList.tsx @@ -0,0 +1,37 @@ +import { FormattedMessage } from 'react-intl'; +import Link from 'next/link'; + +import LocalisedLink from '../LocalisedLink'; +import { useNavigation } from '../../hooks/useNavigation'; + +import type { NodeVersionData } from '../../types'; + +type DownloadListProps = Pick; + +const DownloadList = (props: DownloadListProps) => { + const { getSideNavigation } = useNavigation(); + + const [, ...downloadNavigation] = getSideNavigation('download', { + shaSums: { nodeVersion: props.node }, + allDownloads: { nodeVersion: props.node }, + }); + + return ( +
+
    + {downloadNavigation.map((item, key) => ( +
  • + {item.text} + {item.key === 'shaSums' && ( + + + + )} +
  • + ))} +
+
+ ); +}; + +export default DownloadList; diff --git a/components/Downloads/DownloadReleasesTable.tsx b/components/Downloads/DownloadReleasesTable.tsx new file mode 100644 index 000000000000..79a8505c6bb9 --- /dev/null +++ b/components/Downloads/DownloadReleasesTable.tsx @@ -0,0 +1,55 @@ +import { FormattedMessage } from 'react-intl'; +import Link from 'next/link'; + +import { getNodejsChangelog } from '../../util/getNodeJsChangelog'; +import { getNodeApiLink } from '../../util/getNodeApiLink'; + +import type { ExtendedNodeVersionData } from '../../types'; + +type DownloadReleasesTableProps = { releases: ExtendedNodeVersionData[] }; + +const DownloadReleasesTable = ({ releases }: DownloadReleasesTableProps) => ( + + + + + + + + + + + + + + {releases.map((release, key) => ( + + + + + + + + + + ))} + +
VersionLTSDateV8npm + NODE_MODULE_VERSION[1] + +
Node.js {release.nodeNumeric}{release.ltsName} + + {release.v8}{release.npm}{release.modules} + + + + + + + + + +
+); + +export default DownloadReleasesTable; diff --git a/components/Downloads/PrimaryDownloadMatrix.tsx b/components/Downloads/PrimaryDownloadMatrix.tsx new file mode 100644 index 000000000000..bc79c1b22614 --- /dev/null +++ b/components/Downloads/PrimaryDownloadMatrix.tsx @@ -0,0 +1,222 @@ +import Link from 'next/link'; +import classNames from 'classnames'; + +import LocalisedLink from '../LocalisedLink'; +import { useNextraContext } from '../../hooks/useNextraContext'; + +import type { NodeVersionData, LegacyDownloadsFrontMatter } from '../../types'; + +type PrimaryDownloadMatrixProps = Pick< + NodeVersionData, + 'isLts' | 'node' | 'nodeNumeric' | 'npm' +>; + +// @TODO: Instead of using a static list it should be created dynamically. This is done on `nodejs.dev` +// since this is a temporary solution and going to be fixed in the future. +const PrimaryDownloadMatrix = (props: PrimaryDownloadMatrixProps) => { + const nextraContext = useNextraContext(); + + const { downloads } = nextraContext.frontMatter as LegacyDownloadsFrontMatter; + + const getIsVersionClassName = (isCurrent: boolean) => + classNames({ 'is-version': isCurrent }); + + return ( +
+

+ {downloads.currentVersion}: {props.nodeNumeric} ( + {downloads.includes || 'includes'} npm {props.npm}) +

+

{downloads.intro}

+ +
+
    +
  • + +
    {downloads.lts}
    +
    {downloads['tagline-lts']}
    +
    +
  • +
  • + +
    {downloads.current}
    +
    {downloads['tagline-current']}
    +
    +
  • +
+
    +
  • + + + + + {downloads.WindowsInstaller} +

    node-{props.node}-x86.msi

    + +
  • +
  • + + + + + {downloads.MacOSInstaller} +

    node-{props.node}.pkg

    + +
  • +
  • + + + + + {downloads.SourceCode} +

    node-{props.node}.tar.gz

    + +
  • +
+
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
{downloads.WindowsInstaller} (.msi) + + 32-bit + + + + 64-bit + +
{downloads.WindowsBinary} (.zip) + + 32-bit + + + + 64-bit + +
{downloads.MacOSInstaller} (.pkg) + + 64-bit / ARM64 + +
{downloads.MacOSBinary} (.tar.gz) + + 64-bit + + + + ARM64 + +
{downloads.LinuxBinaries} (x64) + + 64-bit + +
{downloads.LinuxBinaries} (ARM) + + ARMv7 + + + + ARMv8 + +
{downloads.SourceCode} + + node-{props.node}.tar.gz + +
+
+ ); +}; + +export default PrimaryDownloadMatrix; diff --git a/components/Downloads/SecondaryDownloadMatrix.tsx b/components/Downloads/SecondaryDownloadMatrix.tsx new file mode 100644 index 000000000000..19e4facba91d --- /dev/null +++ b/components/Downloads/SecondaryDownloadMatrix.tsx @@ -0,0 +1,71 @@ +import Link from 'next/link'; + +import DownloadList from './DownloadList'; +import { useNextraContext } from '../../hooks/useNextraContext'; + +import type { NodeVersionData, LegacyDownloadsFrontMatter } from '../../types'; + +type SecondaryDownloadMatrixProps = Pick; + +// @TODO: Instead of using a static list it should be created dynamically. This is done on `nodejs.dev` +// since this is a temporary solution and going to be fixed in the future. +const SecondaryDownloadMatrix = (props: SecondaryDownloadMatrixProps) => { + const nextraContext = useNextraContext(); + + const { additional } = + nextraContext.frontMatter as LegacyDownloadsFrontMatter; + + return ( +
+

{additional.headline}

+ + + + + + + + + + + + + + + + + + + + + +
{additional.DockerImage} + + {additional.officialDockerImage} + +
{additional.LinuxPowerSystems} + + 64-bit + +
{additional.LinuxSystemZ} + + 64-bit + +
{additional.AIXPowerSystems} + + 64-bit + +
+ + +
+ ); +}; + +export default SecondaryDownloadMatrix; diff --git a/components/Footer.tsx b/components/Footer.tsx new file mode 100644 index 000000000000..8a5cf25adeb4 --- /dev/null +++ b/components/Footer.tsx @@ -0,0 +1,72 @@ +import { FormattedMessage } from 'react-intl'; +import Link from 'next/link'; + +type FooterProps = { className?: string }; + +// Note.: We don't expect to translate these items as we're going to replace with `nodejs/nodejs.dev` footer +const Footer = ({ className }: FooterProps) => ( + <> +
+ + ↑ + + +
+
+
+

+ Copyright OpenJS Foundation{' '} + and Node.js contributors. All rights reserved. The{' '} + OpenJS Foundation has + registered trademarks and uses trademarks. For a list of trademarks + of the OpenJS Foundation, + please see our{' '} + + Trademark Policy + {' '} + and{' '} + + Trademark List + + . Trademarks and logos not indicated on the{' '} + + list of OpenJS Foundation trademarks + {' '} + are trademarks™ or registered® trademarks of their + respective holders. Use of them does not imply any affiliation with + or endorsement by them. +

+

+ The OpenJS Foundation +  |  + Terms of Use +  |  + + Privacy Policy + +  |  + Bylaws |  + + Code of Conduct + +  |  + + Trademark Policy + +  |  + + Trademark List + +  |  + + Cookie Policy + +

+
+
+
+
+ +); + +export default Footer; diff --git a/components/Header.tsx b/components/Header.tsx new file mode 100644 index 000000000000..6b7d6a0117cd --- /dev/null +++ b/components/Header.tsx @@ -0,0 +1,89 @@ +import { useIntl } from 'react-intl'; +import Image from 'next/image'; +import classNames from 'classnames'; + +import LocalisedLink from './LocalisedLink'; +import { useLocale } from '../hooks/useLocale'; +import { useNavigation } from '../hooks/useNavigation'; +import { useRouter } from 'next/router'; + +const Header = () => { + const { availableLocales, isCurrentLocaleRoute } = useLocale(); + const { navigationItems } = useNavigation(); + const { formatMessage } = useIntl(); + const { asPath } = useRouter(); + + const getLinkClassName = (href: string) => + classNames({ active: isCurrentLocaleRoute(href, href !== '/') }); + + const toggleLanguage = formatMessage({ + id: 'componets.header.buttons.toggleLanguage', + }); + + const toggleDarkMode = formatMessage({ + id: 'components.header.buttons.toggleDarkMode', + }); + + const currentRouteLocalized = (locale: string) => + asPath.replace(/^\/[a-zA-Z-]+/, `/${locale}`); + + return ( +
+
+ + Node.js + + + + +
+
+ + +
+
+ ); +}; + +export default Header; diff --git a/components/Home/Banner.tsx b/components/Home/Banner.tsx new file mode 100644 index 000000000000..12cfeeef6835 --- /dev/null +++ b/components/Home/Banner.tsx @@ -0,0 +1,39 @@ +import Link from 'next/link'; + +import { useSiteConfig } from '../../hooks/useSiteConfig'; +import { dateIsBetween } from '../../util/dateIsBetween'; + +const Banner = () => { + const siteConfig = useSiteConfig(); + + // Note.: This is hardcoded and going to be replaced by the `nodejs/nodejs.dev` codebase + if (siteConfig.websiteBanners && siteConfig.websiteBanners['index']) { + const indexBanner = siteConfig.websiteBanners['index']; + + const showBanner = dateIsBetween( + indexBanner.startDate, + indexBanner.endDate + ); + + if (showBanner && indexBanner.text) { + return ( +

+ {indexBanner.text} +

+ ); + } + + if (showBanner && indexBanner.html) { + return ( + + ); + } + } + + return null; +}; + +export default Banner; diff --git a/components/Home/HomeDownloadButton.tsx b/components/Home/HomeDownloadButton.tsx new file mode 100644 index 000000000000..707a4a4456c3 --- /dev/null +++ b/components/Home/HomeDownloadButton.tsx @@ -0,0 +1,57 @@ +import Link from 'next/link'; + +import LocalisedLink from '../LocalisedLink'; +import { useNextraContext } from '../../hooks/useNextraContext'; +import { getNodejsChangelog } from '../../util/getNodeJsChangelog'; + +import type { NodeVersionData } from '../../types'; + +type HomeDownloadButtonProps = Pick< + NodeVersionData, + 'isLts' | 'node' | 'nodeMajor' | 'nodeNumeric' +>; + +const HomeDownloadButton = (props: HomeDownloadButtonProps) => { + const { + frontMatter: { labels }, + } = useNextraContext(); + + const nodeDownloadLink = `https://nodejs.org/dist/${props.node}/`; + const nodeApiLink = `https://nodejs.org/dist/latest-${props.nodeMajor}/docs/api/`; + + const nodeDownloadTitle = + `${labels.download} ${props.nodeNumeric}` + + ` ${labels[props.isLts ? 'lts' : 'current']}`; + + return ( +
+ + {props.nodeNumeric} {labels[props.isLts ? 'lts' : 'current']} + {labels[`tagline-${props.isLts ? 'lts' : 'current'}`]} + + +
    +
  • + + {labels['other-downloads']} + +
  • +
  • + + {labels.changelog} + +
  • +
  • + {labels.api} +
  • +
+
+ ); +}; + +export default HomeDownloadButton; diff --git a/components/HtmlHead.tsx b/components/HtmlHead.tsx new file mode 100644 index 000000000000..124565c724b2 --- /dev/null +++ b/components/HtmlHead.tsx @@ -0,0 +1,60 @@ +import { useRouter } from 'next/router'; +import Head from 'next/head'; + +import { useSiteConfig } from '../hooks/useSiteConfig'; +import { useLocale } from '../hooks/useLocale'; + +import type { LegacyFrontMatter } from '../types'; + +type HeaderProps = { frontMatter: LegacyFrontMatter }; + +const HtmlHead = ({ frontMatter }: HeaderProps) => { + const siteConfig = useSiteConfig(); + const { currentLocale } = useLocale(); + const { route } = useRouter(); + + const pageTitle = frontMatter.title || siteConfig.title; + const canonicalLink = `https://nodejs.org/${currentLocale.code}${route}`; + + return ( + + {siteConfig.title} + + + + + + + + + + + + + + + + + + + + + + + + + + {siteConfig.rssFeeds.map(feed => ( + + ))} + + ); +}; + +export default HtmlHead; diff --git a/components/LocalisedLink.tsx b/components/LocalisedLink.tsx new file mode 100644 index 000000000000..78e318574fa3 --- /dev/null +++ b/components/LocalisedLink.tsx @@ -0,0 +1,30 @@ +import { useMemo } from 'react'; +import Link from 'next/link'; +import type { ComponentProps } from 'react'; + +import { useLocale } from '../hooks/useLocale'; +import { linkWithLocale } from '../util/linkWithLocale'; + +const LocalisedLink = (props: ComponentProps) => { + const { href, children, ...extra } = props; + + const { currentLocale } = useLocale(); + + const localisedUrl = linkWithLocale(currentLocale.code); + + const finalHref = useMemo( + () => + /^https?:\/\//.test(href.toString()) + ? href.toString() + : localisedUrl(href), + [href, localisedUrl] + ); + + return ( + + {children} + + ); +}; + +export default LocalisedLink; diff --git a/components/Pagination.tsx b/components/Pagination.tsx new file mode 100644 index 000000000000..3219d3249de3 --- /dev/null +++ b/components/Pagination.tsx @@ -0,0 +1,23 @@ +import { FormattedMessage } from 'react-intl'; + +import LocalisedLink from './LocalisedLink'; + +type PaginationProps = { prevSlug?: string; nextSlug?: string }; + +const Pagination = (props: PaginationProps) => ( + +); + +export default Pagination; diff --git a/components/SideNavigation.tsx b/components/SideNavigation.tsx new file mode 100644 index 000000000000..4c3dbe35134b --- /dev/null +++ b/components/SideNavigation.tsx @@ -0,0 +1,36 @@ +import classNames from 'classnames'; + +import LocalisedLink from './LocalisedLink'; +import { useLocale } from '../hooks/useLocale'; +import { useNavigation } from '../hooks/useNavigation'; + +import type { NavigationKeys } from '../types'; + +type SideNavigationProps = { + navigationKey: NavigationKeys; + context?: Record>; +}; + +const SideNavigation = ({ navigationKey, context }: SideNavigationProps) => { + const { getSideNavigation } = useNavigation(); + const { isCurrentLocaleRoute } = useLocale(); + + const sideNavigationItems = getSideNavigation(navigationKey, context); + + const getLinkClassName = (href: string) => + classNames({ active: isCurrentLocaleRoute(href) }); + + return ( + + ); +}; + +export default SideNavigation; diff --git a/crowdin.yml b/crowdin.yml index 70e9029bdb92..852d84809eee 100644 --- a/crowdin.yml +++ b/crowdin.yml @@ -1,20 +1,17 @@ files: - - source: /locale/en/**/*.md - translation: /locale/%two_letters_code%/**/%original_file_name% + - source: /pages/en/**/*.md + translation: /pages/%two_letters_code%/**/%original_file_name% content_segmentation: 0 ignore: - - /locale/en/blog/**/*.md - - /locale/en/knowledge/**/*.md + - /pages/en/blog/**/*.md languages_mapping: two_letters_code: pt-BR: pt-br zh-CN: zh-cn zh-TW: zh-tw es-ES: es - - source: /locale/en/**/*.json - translation: /locale/%two_letters_code%/**/%original_file_name% - ignore: - - /locale/en/blog/**/*.json + - source: /i18n/locales/en.json + translation: /i18n/locales/%two_letters_code%.json languages_mapping: two_letters_code: pt-BR: pt-br diff --git a/external/survey-2018/package-lock.json b/external/survey-2018/package-lock.json deleted file mode 100644 index a2d6d0c78d5e..000000000000 --- a/external/survey-2018/package-lock.json +++ /dev/null @@ -1,30 +0,0 @@ -{ - "name": "survey-report-2018", - "version": "1.0.0", - "lockfileVersion": 1, - "requires": true, - "dependencies": { - "commander": { - "version": "2.15.1", - "resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz", - "integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==", - "dev": true - }, - "source-map": { - "version": "0.6.1", - "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", - "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==", - "dev": true - }, - "uglify-js": { - "version": "3.3.28", - "resolved": "https://registry.npmjs.org/uglify-js/-/uglify-js-3.3.28.tgz", - "integrity": "sha512-68Rc/aA6cswiaQ5SrE979UJcXX+ADA1z33/ZsPd+fbAiVdjZ16OXdbtGO+rJUUBgK6qdf3SOPhQf3K/ybF5Miw==", - "dev": true, - "requires": { - "commander": "2.15.1", - "source-map": "0.6.1" - } - } - } -} diff --git a/external/survey-2018/package.json b/external/survey-2018/package.json deleted file mode 100644 index f5c798625abc..000000000000 --- a/external/survey-2018/package.json +++ /dev/null @@ -1,10 +0,0 @@ -{ - "name": "survey-report-2018", - "version": "1.0.0", - "scripts": { - "build": "uglifyjs -c -m -o data.min.js data.js && uglifyjs -c -m -o full.min.js full.js && uglifyjs -c -m -o graph.min.js graph.js" - }, - "devDependencies": { - "uglify-js": "^3.3.28" - } -} diff --git a/global.d.ts b/global.d.ts new file mode 100644 index 000000000000..488111db6dc5 --- /dev/null +++ b/global.d.ts @@ -0,0 +1,12 @@ +declare global { + // @TODO: Update this to use the correct type + // eslint-disable-next-line no-unused-vars + var __nextra_pageContext__: Record; + + // eslint-disable-next-line no-unused-vars + interface Window { + startLegacyApp: Function; + } +} + +export default global; diff --git a/hooks/useLocale.ts b/hooks/useLocale.ts new file mode 100644 index 000000000000..b9ff133282fd --- /dev/null +++ b/hooks/useLocale.ts @@ -0,0 +1,28 @@ +import { useContext } from 'react'; +import { useRouter } from 'next/router'; + +import { LocaleContext } from '../providers/localeProvider'; +import { linkWithLocale } from '../util/linkWithLocale'; + +export const useLocale = () => { + const { currentLocale, availableLocales } = useContext(LocaleContext); + const { asPath } = useRouter(); + + const localisedLink = linkWithLocale(currentLocale!.code); + + const localisedPath = (route: string) => + localisedLink(route).replace(/[#|?].*$/, ''); + + return { + availableLocales: availableLocales!, + currentLocale: currentLocale!, + isCurrentLocaleRoute: (route: string, allowSubPath?: boolean) => { + const localisedRoute = localisedPath(route); + const asPathJustPath = asPath.replace(/[#|?].*$/, ''); + + return allowSubPath + ? asPathJustPath.startsWith(localisedRoute) + : localisedRoute === asPathJustPath; + }, + }; +}; diff --git a/hooks/useNavigation.tsx b/hooks/useNavigation.tsx new file mode 100644 index 000000000000..81ef863e9ade --- /dev/null +++ b/hooks/useNavigation.tsx @@ -0,0 +1,45 @@ +import { FormattedMessage } from 'react-intl'; + +import type { NavigationEntry, NavigationKeys } from '../types'; + +import navigation from '../navigation.json'; + +// Translation Context for FormattedMessage +type Context = Record>; + +// Provides Context replacement for variables within the Link. This is also something that is not going +// to happen in the future with `nodejs/nodejs.dev` codebase +const replaceLinkWithContext = (link: string, context: Record) => + Object.entries(context).reduce( + (finalLink, [find, replace]) => finalLink.replace(`{${find}}`, replace), + link + ); + +export const useNavigation = () => { + const mapNavigationEntries = ( + entries: Record, + context?: Context + ) => { + const getContext = (key: string) => (context && context[key]) || {}; + + const getFormattedMessage = (translationId: string, key: string) => ( + + ); + + return Object.entries(entries).map(([key, item]) => ({ + text: getFormattedMessage(item.translationId, key), + link: replaceLinkWithContext(item.link, getContext(key)), + key: key, + })); + }; + + return { + navigationItems: mapNavigationEntries(navigation), + getSideNavigation: (section: NavigationKeys, context?: Context) => + mapNavigationEntries( + // We need the parent and their items when making a side navigation + { [section]: navigation[section], ...navigation[section].items }, + context + ), + }; +}; diff --git a/hooks/useNextraContext.ts b/hooks/useNextraContext.ts new file mode 100644 index 000000000000..19c9b5d7b3fe --- /dev/null +++ b/hooks/useNextraContext.ts @@ -0,0 +1,8 @@ +import { useContext } from 'react'; +import { LayoutContext } from '../providers/layoutProvider'; + +export const useNextraContext = () => { + const { pageOpts, pageProps } = useContext(LayoutContext); + + return { ...pageOpts, ...pageProps }; +}; diff --git a/hooks/useNodeData.ts b/hooks/useNodeData.ts new file mode 100644 index 000000000000..70d7fc143c12 --- /dev/null +++ b/hooks/useNodeData.ts @@ -0,0 +1,17 @@ +import { useContext } from 'react'; +import { NodeDataContext } from '../providers/nodeDataProvider'; +import { NodeVersionData } from '../types'; + +type UseNodeDataReturnType = { + currentNodeVersion?: NodeVersionData; + currentLtsVersion?: NodeVersionData; +}; + +export const useNodeData = (): UseNodeDataReturnType => { + const [currentNodeVersion, currentLtsVersion] = useContext(NodeDataContext); + + return { + currentLtsVersion: currentLtsVersion || currentNodeVersion, + currentNodeVersion, + }; +}; diff --git a/hooks/useSiteConfig.ts b/hooks/useSiteConfig.ts new file mode 100644 index 000000000000..8f18795dcca6 --- /dev/null +++ b/hooks/useSiteConfig.ts @@ -0,0 +1,8 @@ +import { useContext } from 'react'; +import { SiteContext } from '../providers/siteProvider'; + +export const useSiteConfig = () => { + const siteConfigContext = useContext(SiteContext); + + return siteConfigContext; +}; diff --git a/i18n/config.json b/i18n/config.json new file mode 100644 index 000000000000..da0b8e8c6459 --- /dev/null +++ b/i18n/config.json @@ -0,0 +1,173 @@ +[ + { + "code": "ar", + "localName": "العربية", + "name": "Arabic", + "langDir": "rtl", + "dateFormat": "YYYY.MM.DD", + "hrefLang": "ar", + "enabled": true + }, + { + "code": "ca", + "localName": "Catalan", + "name": "Catalan", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "ca", + "enabled": true + }, + { + "code": "de", + "localName": "Deutsch", + "name": "German", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "de", + "enabled": true + }, + { + "code": "he", + "localName": "עברית", + "name": "Hebrew", + "langDir": "rtl", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "he-IL", + "enabled": true + }, + { + "code": "en", + "localName": "English", + "name": "English", + "langDir": "ltr", + "dateFormat": "MM.DD.YYYY", + "hrefLang": "en-US", + "enabled": true + }, + { + "code": "es", + "localName": "Español", + "name": "Spanish", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "es-ES", + "enabled": true + }, + { + "code": "fa", + "localName": "زبان فارسی", + "name": "Persian", + "langDir": "rtl", + "dateFormat": "YYYY.MM.DD", + "hrefLang": "fa", + "enabled": true + }, + { + "code": "fr", + "localName": "Français", + "name": "French", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "fr", + "enabled": true + }, + { + "code": "it", + "localName": "Italiano", + "name": "Italian", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "it", + "enabled": true + }, + { + "code": "ja", + "localName": "日本語", + "name": "Japanese", + "langDir": "ltr", + "dateFormat": "YYYY.MM.DD", + "hrefLang": "ja", + "enabled": true + }, + { + "code": "ka", + "localName": "ქართული", + "name": "Georgian", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "ka", + "enabled": true + }, + { + "code": "ko", + "localName": "한국어", + "name": "Korean", + "langDir": "ltr", + "dateFormat": "YYYY.MM.DD", + "hrefLang": "ko", + "enabled": true + }, + { + "code": "pt-br", + "localName": "Português do Brasil", + "name": "Brazilian Portuguese", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "", + "enabled": true + }, + { + "code": "ro", + "localName": "limba română", + "name": "Romanian", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "ro", + "enabled": true + }, + { + "code": "ru", + "localName": "Русский", + "name": "Russian", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "ru", + "enabled": true + }, + { + "code": "tr", + "localName": "Türkçe", + "name": "Turkish", + "langDir": "rtl", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "tr", + "enabled": true + }, + { + "code": "uk", + "localName": "Українська", + "name": "Ukrainian", + "langDir": "ltr", + "dateFormat": "DD.MM.YYYY", + "hrefLang": "uk", + "enabled": true + }, + { + "code": "zh-cn", + "localName": "简体中文", + "name": "Simplified Chinese", + "langDir": "ltr", + "dateFormat": "YYYY/MM/DD", + "hrefLang": "zh-Hans", + "enabled": true + }, + { + "code": "zh-tw", + "localName": "繁體中文", + "name": "Traditional Chinese", + "langDir": "ltr", + "dateFormat": "YYYY/MM/DD", + "hrefLang": "zh-Hant", + "enabled": true + } +] diff --git a/i18n/locales/ar.json b/i18n/locales/ar.json new file mode 100644 index 000000000000..e83ce5b7e54c --- /dev/null +++ b/i18n/locales/ar.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "إنتقل إلى الأعلى", + "components.header.links.home": "الرئيسية", + "components.header.links.about": "عن الموقع", + "components.header.links.download": "تنزيلات", + "components.header.links.docs": "التوثيق", + "components.header.links.getInvolved": "إنضم إلينا", + "components.header.links.security": "أمن", + "components.header.links.certification": "شهادة", + "components.header.links.blog": "المدونة", + "components.navigation.about.links.governance": "الحوكمة", + "components.navigation.docs.links.es6": "ES6 وما بعدها", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "إرشادات", + "components.navigation.docs.links.dependencies": "تبعيات", + "components.navigation.getInvolved.links.collabSummit": "القمة التعاونية", + "components.navigation.getInvolved.links.contribute": "مساهمة", + "components.navigation.getInvolved.links.codeOfConduct": "القواعد السلوكية", + "components.downloadList.links.previousReleases": "الاصدارات السابقة", + "components.downloadList.links.packageManager": "تحميل Node.js عن طريق نظام إدارة الحزم الافتراضي", + "components.downloadList.links.shaSums": "وثائق الاصدارات مختومة SHASUMS", + "components.downaloadList.links.shaSums.howToVerify": " (كيفية التحقق)", + "components.downloadList.links.allDownloads": "تحميل جميع النسخ", + "components.downloadList.links.nightlyReleases": "إصدارات ليلية", + "components.downloadList.links.unofficialBuilds": "بُنْيَات غير رسمية", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "تثبيت Node.js باستعمال أرشيف ثنائي على لينكس", + "components.downloadList.links.installingOnWsl": "التثبيت على ويندوز في النظام الفرعي لينكس (WSL)", + "components.downloadReleasesTable.changelog": "سجل التغييرات", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "التوثيق", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "التالي | ", + "components.pagination.previous": "السابق", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/ca.json b/i18n/locales/ca.json new file mode 100644 index 000000000000..9ea9edb03203 --- /dev/null +++ b/i18n/locales/ca.json @@ -0,0 +1,40 @@ +{ + "components.footer.scrollToTop.button": "Torna al començament", + "components.header.links.home": "Inici", + "components.header.links.about": "Quant a", + "components.header.links.download": "Descàrregues", + "components.header.links.docs": "Documentació", + "components.header.links.getInvolved": "Participa", + "components.header.links.security": "Seguretat", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Notícies", + "components.navigation.about.links.governance": "Govern", + "components.navigation.docs.links.es6": "ES6 i més enllà", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guies", + "components.navigation.docs.links.dependencies": "Dependències", + "components.navigation.getInvolved.links.collabSummit": "Col·labora en el Summit", + "components.navigation.getInvolved.links.contribute": "Contribueix", + "components.navigation.getInvolved.links.codeOfConduct": "Codi de Conducta", + "components.downloadList.links.previousReleases": "Descarrègues", + "components.downloadList.links.packageManager": "Instal·lar Node.js mitjançant un gestor de paquets", + "components.downloadList.links.shaSums": "Signatures SHASUMS per arxius de versions", + "components.downaloadList.links.shaSums.howToVerify": " (Com verificar-ho)", + "components.downloadList.links.allDownloads": "Totes les opcions de descàrrega", + "components.downloadList.links.nightlyReleases": "Versions Nightly", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Registre de Canvis", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Documentació", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Següent | ", + "components.pagination.previous": "Anterior", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" + } + \ No newline at end of file diff --git a/i18n/locales/de.json b/i18n/locales/de.json new file mode 100644 index 000000000000..ce5356f3f0fb --- /dev/null +++ b/i18n/locales/de.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Zum Seitenanfang", + "components.header.links.home": "Startseite", + "components.header.links.about": "Über Node.js", + "components.header.links.download": "Downloads", + "components.header.links.docs": "Dokumentation", + "components.header.links.getInvolved": "Mitmachen", + "components.header.links.security": "Sicherheit", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Neuigkeiten", + "components.navigation.about.links.governance": "Governance", + "components.navigation.docs.links.es6": "ES6 und darüber hinaus", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Anleitungen", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Mitwirken", + "components.navigation.getInvolved.links.codeOfConduct": "Verhaltenskodex", + "components.downloadList.links.previousReleases": "Alle Versionen", + "components.downloadList.links.packageManager": "Node.js mit Paketmanagern installieren", + "components.downloadList.links.shaSums": "Signierte SHASUMS für die Versionsdateien", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "Alle Download-Optionen", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Inoffizielle Builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Änderungshistorie", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Dokumentation", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Weiter | ", + "components.pagination.previous": "Zurück", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/en.json b/i18n/locales/en.json new file mode 100644 index 000000000000..9dbf6ec601e9 --- /dev/null +++ b/i18n/locales/en.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.home": "Home", + "components.header.links.about": "About", + "components.header.links.download": "Downloads", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.navigation.about.links.governance": "Governance", + "components.navigation.docs.links.es6": "ES6 and beyond", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.previousReleases": "Previous Releases", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/es.json b/i18n/locales/es.json new file mode 100644 index 000000000000..6129daa8d9b8 --- /dev/null +++ b/i18n/locales/es.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Vuelve arriba", + "components.header.links.home": "Inicio", + "components.header.links.about": "Acerca", + "components.header.links.download": "Descargas", + "components.header.links.docs": "Documentación", + "components.header.links.getInvolved": "Participe", + "components.header.links.security": "Seguridad", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Noticias", + "components.navigation.about.links.governance": "Dirección", + "components.navigation.docs.links.es6": "ES6 y más allá", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guías", + "components.navigation.docs.links.dependencies": "Dependencias", + "components.navigation.getInvolved.links.collabSummit": "Colabore en el Summit", + "components.navigation.getInvolved.links.contribute": "Contribuya", + "components.navigation.getInvolved.links.codeOfConduct": "Código de Conducta", + "components.downloadList.links.previousReleases": "Versiones anteriores", + "components.downloadList.links.packageManager": "Instale Node.js mediante un gestor de paquetes", + "components.downloadList.links.shaSums": "Firmas SHASUMS de los archivos de versiones", + "components.downaloadList.links.shaSums.howToVerify": " (Cómo verificarlo)", + "components.downloadList.links.allDownloads": "Todas las opciones de descarga", + "components.downloadList.links.nightlyReleases": "Versiones Nightly", + "components.downloadList.links.unofficialBuilds": "Construcciones no oficiales", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Instalación de Node.js a través del archivo binario", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Registro de Cambios", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Documentación", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Siguiente | ", + "components.pagination.previous": "Anterior", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/fa.json b/i18n/locales/fa.json new file mode 100644 index 000000000000..0a4351b69bc6 --- /dev/null +++ b/i18n/locales/fa.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "رفتن به بالا", + "components.header.links.home": "خانه", + "components.header.links.about": "درباره", + "components.header.links.download": "دانلود‌ها", + "components.header.links.docs": "اسناد", + "components.header.links.getInvolved": "مشارکت جستن", + "components.header.links.security": "امنیت", + "components.header.links.certification": "Certification", + "components.header.links.blog": "بلاگ", + "components.navigation.about.links.governance": "مدیریت", + "components.navigation.docs.links.es6": "ES6 و فراتر", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "راهنمایی‌ها", + "components.navigation.docs.links.dependencies": "وابستگی‌ها", + "components.navigation.getInvolved.links.collabSummit": "نشت مشارکت کنندگان", + "components.navigation.getInvolved.links.contribute": "مشارکت", + "components.navigation.getInvolved.links.codeOfConduct": "شیوه تعامل برای مشارکت", + "components.downloadList.links.previousReleases": "انتشارهای پیشین", + "components.downloadList.links.packageManager": "نصب نودجی‌اس با package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downaloadList.links.shaSums.howToVerify": " (چگونه راستی‌آزمایی کنیم؟)", + "components.downloadList.links.allDownloads": "تمام گزینه‌ها برای دانلود", + "components.downloadList.links.nightlyReleases": "ساخت‌های شبانه", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "تغییرات", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "اسناد", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "بعدی | ", + "components.pagination.previous": "قبلی", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/fr.json b/i18n/locales/fr.json new file mode 100644 index 000000000000..50c8f5e4ec16 --- /dev/null +++ b/i18n/locales/fr.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Faire défiler en haut", + "components.header.links.home": "Accueil", + "components.header.links.about": "À propos", + "components.header.links.download": "Téléchargements", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "S’impliquer", + "components.header.links.security": "Securité", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Actualités", + "components.navigation.about.links.governance": "Governance", + "components.navigation.docs.links.es6": "ES6 et au-delà", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribuer", + "components.navigation.getInvolved.links.codeOfConduct": "Code de conduite", + "components.downloadList.links.previousReleases": "Versions précédentes", + "components.downloadList.links.packageManager": "Installer Node.js via le gestionnaire de paquets", + "components.downloadList.links.shaSums": "SHASUMS signés pour les fichiers des versions", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "Toutes les options de téléchargement", + "components.downloadList.links.nightlyReleases": "Versions quotidiennes", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Journal des modifications", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/gl.json b/i18n/locales/gl.json new file mode 100644 index 000000000000..511b85dab8f9 --- /dev/null +++ b/i18n/locales/gl.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Volta ao principio", + "components.header.links.home": "Inicio", + "components.header.links.about": "Acerca de", + "components.header.links.download": "Descargas", + "components.header.links.docs": "Documentación", + "components.header.links.getInvolved": "Participa", + "components.header.links.security": "Seguridade", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Noticias", + "components.navigation.about.links.governance": "Goberno", + "components.navigation.docs.links.es6": "ES6 e máis aló", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guías", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribúe", + "components.navigation.getInvolved.links.codeOfConduct": "Comportamento", + "components.downloadList.links.previousReleases": "Versións anteriores", + "components.downloadList.links.packageManager": "Instalar Node.js usando un xestor de paquetes", + "components.downloadList.links.shaSums": "Firmas SHASUMS para os arquivos de versións", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "Todas as opcións de descarga", + "components.downloadList.links.nightlyReleases": "Versións Nightly", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Cambios", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Documentación", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Seguinte | ", + "components.pagination.previous": "Anterior", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/it.json b/i18n/locales/it.json new file mode 100644 index 000000000000..c70de9a6f7bb --- /dev/null +++ b/i18n/locales/it.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Portami all'inizio", + "components.header.links.home": "Home", + "components.header.links.about": "Informazioni", + "components.header.links.download": "Downloads", + "components.header.links.docs": "Documentazione", + "components.header.links.getInvolved": "Come partecipare", + "components.header.links.security": "Sicurezza", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Blog", + "components.navigation.about.links.governance": "Gestione", + "components.navigation.docs.links.es6": "ES6 e oltre", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guide", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribuire", + "components.navigation.getInvolved.links.codeOfConduct": "Condotta", + "components.downloadList.links.previousReleases": "Rilasci Precedenti", + "components.downloadList.links.packageManager": "Installa Node.js con un gestore di pacchetti", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "Tutti i download", + "components.downloadList.links.nightlyReleases": "Build notturne", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Registro modifiche", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Documentazione", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Successiva | ", + "components.pagination.previous": "Precedente", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/ja.json b/i18n/locales/ja.json new file mode 100644 index 000000000000..2f7b2c622fe4 --- /dev/null +++ b/i18n/locales/ja.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "上部へスクロールする", + "components.header.links.home": "ホーム", + "components.header.links.about": "Node.js とは", + "components.header.links.download": "ダウンロード", + "components.header.links.docs": "ドキュメント", + "components.header.links.getInvolved": "参加する", + "components.header.links.security": "セキュリティ", + "components.header.links.certification": "Certification", + "components.header.links.blog": "ニュース", + "components.navigation.about.links.governance": "委員会", + "components.navigation.docs.links.es6": "ES6 について", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "ガイド", + "components.navigation.docs.links.dependencies": "依存関係", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "貢献する", + "components.navigation.getInvolved.links.codeOfConduct": "行動規範", + "components.downloadList.links.previousReleases": "バージョンの一覧", + "components.downloadList.links.packageManager": "Iパッケージマネージャを使用したダウンロード", + "components.downloadList.links.shaSums": "リリースファイルのための SHASUM 署名", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "非公式のビルド版", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "変更履歴", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "ドキュメント", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "次 | ", + "components.pagination.previous": "前", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/ka.json b/i18n/locales/ka.json new file mode 100644 index 000000000000..ca636c9e5cac --- /dev/null +++ b/i18n/locales/ka.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "ზემოთ", + "components.header.links.home": "მთავარი", + "components.header.links.about": "შესახებ", + "components.header.links.download": "ჩამოტვირთვა", + "components.header.links.docs": "დოკუმენტაცია", + "components.header.links.getInvolved": "შემოგვიერთდით", + "components.header.links.security": "უსაფრთხოება", + "components.header.links.certification": "სერტიფიკაცია", + "components.header.links.blog": "სიახლეები", + "components.navigation.about.links.governance": "მმართველობა", + "components.navigation.docs.links.es6": "ES6 და მის ფარგლებს მიღმა", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "სახელმძღვანელოები", + "components.navigation.docs.links.dependencies": "დაქვემდებარებულები (Dependencies)", + "components.navigation.getInvolved.links.collabSummit": "თანამშრომლობის სამიტი", + "components.navigation.getInvolved.links.contribute": "ხელშეწყობა", + "components.navigation.getInvolved.links.codeOfConduct": "ყოფაქცევის კოდექსი", + "components.downloadList.links.previousReleases": "უწინდელი ვერსიები", + "components.downloadList.links.packageManager": "Node.js-ის ინსტალაცია პაკეტის მენეჯერის გამოყენებით", + "components.downloadList.links.shaSums": "ხელმოწერილი SHASUMS გამოშვების (release) ფაილებისათვის", + "components.downaloadList.links.shaSums.howToVerify": " (როგორ გადავამოწმოთ)", + "components.downloadList.links.allDownloads": "ჩამოტვირთვის ყველა ვარიანტი", + "components.downloadList.links.nightlyReleases": "ღამის ვერსიები", + "components.downloadList.links.unofficialBuilds": "არაოფიციალური ვერსიები", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Node.js-ის ინსტალაცია ბინარული (binary) არქივის გამოყენებით", + "components.downloadList.links.installingOnWsl": "ინსტალაცია Windows-ის Linux-ქვესისტემისათვის (WSL)", + "components.downloadReleasesTable.changelog": "ცვლილებათა ჩამონათვალი", + "components.downloadReleasesTable.releases": "უწინდელი ვერსიები", + "components.downloadReleasesTable.docs": "დოკუმენტაცია", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "გადართვა მუქ/ნათელ რეჟიმზე", + "components.pagination.next": "შემდეგი | ", + "components.pagination.previous": "წინა", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/ko.json b/i18n/locales/ko.json new file mode 100644 index 000000000000..ff50aa834d3b --- /dev/null +++ b/i18n/locales/ko.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "맨 위로", + "components.header.links.home": "홈", + "components.header.links.about": "About", + "components.header.links.download": "다운로드", + "components.header.links.docs": "문서", + "components.header.links.getInvolved": "참여하기", + "components.header.links.security": "보안", + "components.header.links.certification": "Certification", + "components.header.links.blog": "뉴스", + "components.navigation.about.links.governance": "거버넌스", + "components.navigation.docs.links.es6": "ES6와 그 이후", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "안내", + "components.navigation.docs.links.dependencies": "의존성", + "components.navigation.getInvolved.links.collabSummit": "협업자 서밋", + "components.navigation.getInvolved.links.contribute": "기여하기", + "components.navigation.getInvolved.links.codeOfConduct": "행동강령", + "components.downloadList.links.previousReleases": "이전 릴리스", + "components.downloadList.links.packageManager": "패키지 관리자를 통한 Node.js 설치", + "components.downloadList.links.shaSums": "릴리스 파일에 서명된 SHASUMS", + "components.downaloadList.links.shaSums.howToVerify": " (검증 방법)", + "components.downloadList.links.allDownloads": "모든 다운로드 보기", + "components.downloadList.links.nightlyReleases": "나이틀리 빌드", + "components.downloadList.links.unofficialBuilds": "비공식 빌드", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Linux에서 바이너리 아카이브를 통해 Node.js 설치하기", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "변경사항", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "문서", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "다음 | ", + "components.pagination.previous": "이전", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/nl.json b/i18n/locales/nl.json new file mode 100644 index 000000000000..e8d7e33bbc6a --- /dev/null +++ b/i18n/locales/nl.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Scroll naar boven", + "components.header.links.home": "Home", + "components.header.links.about": "Over Node.js", + "components.header.links.download": "Downloads", + "components.header.links.docs": "Documentatie", + "components.header.links.getInvolved": "Raak Betrokken", + "components.header.links.security": "Security", + "components.header.links.certification": "Certificering", + "components.header.links.blog": "Nieuws", + "components.navigation.about.links.governance": "Bestuur", + "components.navigation.docs.links.es6": "ES6 en meer", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Handleidingen", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Bijdragen", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.previousReleases": "Vorige Versies", + "components.downloadList.links.packageManager": "Installeer Node.js via package manager", + "components.downloadList.links.shaSums": "Ondertekende SHASUMS voor release bestanden", + "components.downaloadList.links.shaSums.howToVerify": " (Hoe verifiëren?)", + "components.downloadList.links.allDownloads": "Alle download opties", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Onofficiële builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installeer Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Installeer op Windows Subsystem voor Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Documentatie", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Volgende | ", + "components.pagination.previous": "Vorige", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/pt-br.json b/i18n/locales/pt-br.json new file mode 100644 index 000000000000..0183e8e7b007 --- /dev/null +++ b/i18n/locales/pt-br.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Retorne ao começo", + "components.header.links.home": "Início", + "components.header.links.about": "Sobre", + "components.header.links.download": "Download", + "components.header.links.docs": "Documentação", + "components.header.links.getInvolved": "Participe", + "components.header.links.security": "Segurança", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Novidades", + "components.navigation.about.links.governance": "Governança do Projeto", + "components.navigation.docs.links.es6": "ES6 e além", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guias", + "components.navigation.docs.links.dependencies": "Dependências", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribua", + "components.navigation.getInvolved.links.codeOfConduct": "Código de Conduta", + "components.downloadList.links.previousReleases": "Versões Anteriores", + "components.downloadList.links.packageManager": "Instale Node.js usando gerenciador de pacotes.", + "components.downloadList.links.shaSums": "SHASUMS assinados para arquivos de versões", + "components.downaloadList.links.shaSums.howToVerify": " (Como verificar)", + "components.downloadList.links.allDownloads": "Todas as opções de download", + "components.downloadList.links.nightlyReleases": "Versões Nightly", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Instalando Node.js via arquivo binário.", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Documentação", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Próximo | ", + "components.pagination.previous": "Anterior", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/ro.json b/i18n/locales/ro.json new file mode 100644 index 000000000000..9dbf6ec601e9 --- /dev/null +++ b/i18n/locales/ro.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Scroll to top", + "components.header.links.home": "Home", + "components.header.links.about": "About", + "components.header.links.download": "Downloads", + "components.header.links.docs": "Docs", + "components.header.links.getInvolved": "Get Involved", + "components.header.links.security": "Security", + "components.header.links.certification": "Certification", + "components.header.links.blog": "News", + "components.navigation.about.links.governance": "Governance", + "components.navigation.docs.links.es6": "ES6 and beyond", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Guides", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "Collab Summit", + "components.navigation.getInvolved.links.contribute": "Contribute", + "components.navigation.getInvolved.links.codeOfConduct": "Code of Conduct", + "components.downloadList.links.previousReleases": "Previous Releases", + "components.downloadList.links.packageManager": "Installing Node.js via package manager", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "All download options", + "components.downloadList.links.nightlyReleases": "Nightly builds", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Changelog", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Docs", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Newer | ", + "components.pagination.previous": "Older", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/ru.json b/i18n/locales/ru.json new file mode 100644 index 000000000000..0356947615fb --- /dev/null +++ b/i18n/locales/ru.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Вверх", + "components.header.links.home": "Главная", + "components.header.links.about": "О проекте", + "components.header.links.download": "Загрузка", + "components.header.links.docs": "Документация", + "components.header.links.getInvolved": "Присоединиться", + "components.header.links.security": "Безопасность", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Новости", + "components.navigation.about.links.governance": "Управление", + "components.navigation.docs.links.es6": "ES6 и выше", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Руководства", + "components.navigation.docs.links.dependencies": "Зависимости", + "components.navigation.getInvolved.links.collabSummit": "Саммит сотрудников", + "components.navigation.getInvolved.links.contribute": "Участие", + "components.navigation.getInvolved.links.codeOfConduct": "Правила", + "components.downloadList.links.previousReleases": "Предыдущие релизы", + "components.downloadList.links.packageManager": "Установка Node.js с помощью пакетного менеджера", + "components.downloadList.links.shaSums": "Подписанные SHASUMS для файлов релиза", + "components.downaloadList.links.shaSums.howToVerify": " (Как проверить)", + "components.downloadList.links.allDownloads": "Все варианты загрузки", + "components.downloadList.links.nightlyReleases": "Ночные сборки", + "components.downloadList.links.unofficialBuilds": "Неофициальные сборки", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Установка Node.js через бинарный архив в Linux", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Список изменений", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Документация", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Следующий | ", + "components.pagination.previous": "Предыдущий", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/tr.json b/i18n/locales/tr.json new file mode 100644 index 000000000000..ba8b4889a68d --- /dev/null +++ b/i18n/locales/tr.json @@ -0,0 +1,40 @@ +{ + "components.footer.scrollToTop.button": "Yukarı", + "components.header.links.home": "Anasayfa", + "components.header.links.about": "Hakkında", + "components.header.links.download": "İndir", + "components.header.links.docs": "Belgeler", + "components.header.links.getInvolved": "Katıl", + "components.header.links.security": "Güvenlik", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Haberler", + "components.navigation.about.links.governance": "Yönetim", + "components.navigation.docs.links.es6": "ES6 ve ötesi", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Rehberler", + "components.navigation.docs.links.dependencies": "Bağımlılıklar", + "components.navigation.getInvolved.links.collabSummit": "İşbirliği Zirvesi", + "components.navigation.getInvolved.links.contribute": "Katkıda bulunmak", + "components.navigation.getInvolved.links.codeOfConduct": "Davranış Kuralları", + "components.downloadList.links.previousReleases": "Önceki Sürümler", + "components.downloadList.links.packageManager": "Node.js'i paket yöneticisi ile kurmak", + "components.downloadList.links.shaSums": "Sürüm dosyaları için İmzalı SHASUMS", + "components.downaloadList.links.shaSums.howToVerify": " (Doğrulama nasıl yapılır)", + "components.downloadList.links.allDownloads": "Tüm indirme seçenekleri", + "components.downloadList.links.nightlyReleases": "Gecelik Sürümler", + "components.downloadList.links.unofficialBuilds": "Resmi Olmayan Sürümler", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Linux'ta ikili(binary) arşiv yoluyla Node.js kurulumu", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Değişiklikler", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Belgeler", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Sonraki | ", + "components.pagination.previous": "Önceki", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" + } + \ No newline at end of file diff --git a/i18n/locales/uk.json b/i18n/locales/uk.json new file mode 100644 index 000000000000..7d515a93df22 --- /dev/null +++ b/i18n/locales/uk.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "Вгору", + "components.header.links.home": "Головна", + "components.header.links.about": "Про проект", + "components.header.links.download": "Завантаження", + "components.header.links.docs": "Документація", + "components.header.links.getInvolved": "Приєднатись", + "components.header.links.security": "Безпека", + "components.header.links.certification": "Certification", + "components.header.links.blog": "Новини", + "components.navigation.about.links.governance": "Управління", + "components.navigation.docs.links.es6": "ES6 і вище", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "Керівництва", + "components.navigation.docs.links.dependencies": "Залежності", + "components.navigation.getInvolved.links.collabSummit": "Саміт співпраці", + "components.navigation.getInvolved.links.contribute": "Сприяння", + "components.navigation.getInvolved.links.codeOfConduct": "Правила", + "components.downloadList.links.previousReleases": "Попередні Релізи", + "components.downloadList.links.packageManager": "Встановлення Node.js через пакетний менеджер", + "components.downloadList.links.shaSums": "Підписані SHASUMS для файлів релізу", + "components.downaloadList.links.shaSums.howToVerify": " (Як перевірити)", + "components.downloadList.links.allDownloads": "Всі варіанти завантажень", + "components.downloadList.links.nightlyReleases": "Нічні збірки", + "components.downloadList.links.unofficialBuilds": "Unofficial builds", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "Installing Node.js via binary archive", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "Список змін", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "Документація", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "Далі | ", + "components.pagination.previous": "Попередній", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/zh-cn.json b/i18n/locales/zh-cn.json new file mode 100644 index 000000000000..148d15bd113d --- /dev/null +++ b/i18n/locales/zh-cn.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "回到页顶", + "components.header.links.home": "首页", + "components.header.links.about": "关于", + "components.header.links.download": "下载", + "components.header.links.docs": "文档", + "components.header.links.getInvolved": "加入我们", + "components.header.links.security": "安全", + "components.header.links.certification": "相关认证", + "components.header.links.blog": "新闻", + "components.navigation.about.links.governance": "管理规则", + "components.navigation.docs.links.es6": "ES6 及更高", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "指南", + "components.navigation.docs.links.dependencies": "依赖项", + "components.navigation.getInvolved.links.collabSummit": "协作者峰会", + "components.navigation.getInvolved.links.contribute": "贡献", + "components.navigation.getInvolved.links.codeOfConduct": "管理", + "components.downloadList.links.previousReleases": "以往的版本", + "components.downloadList.links.packageManager": "使用包管理器安装 Node.js", + "components.downloadList.links.shaSums": "Signed SHASUMS for release files", + "components.downaloadList.links.shaSums.howToVerify": " (如何校验)", + "components.downloadList.links.allDownloads": "所有下载选项", + "components.downloadList.links.nightlyReleases": "每日构建", + "components.downloadList.links.unofficialBuilds": "非官方构建版", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "在 Linux 上,通过二进制文件安装 Node.js", + "components.downloadList.links.installingOnWsl": "在适用于 Linux 的 Windows 子系统(WSL)上安装 Node.js", + "components.downloadReleasesTable.changelog": "更新日志", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "文档", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "下一个 | ", + "components.pagination.previous": "以前", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/i18n/locales/zh-tw.json b/i18n/locales/zh-tw.json new file mode 100644 index 000000000000..9fd6ed80c78b --- /dev/null +++ b/i18n/locales/zh-tw.json @@ -0,0 +1,39 @@ +{ + "components.footer.scrollToTop.button": "回到頁首", + "components.header.links.home": "首頁", + "components.header.links.about": "關於我們", + "components.header.links.download": "下載", + "components.header.links.docs": "文件", + "components.header.links.getInvolved": "加入我們", + "components.header.links.security": "安全", + "components.header.links.certification": "相關認證", + "components.header.links.blog": "部落格", + "components.navigation.about.links.governance": "管理規則", + "components.navigation.docs.links.es6": "ES6 相關", + "components.navigation.docs.links.apiLts": "{fullLtsNodeVersion} API {spanLts}", + "components.navigation.docs.links.apiCurrent": "{fullCurrentNodeVersion} API", + "components.navigation.docs.links.guides": "技術指南", + "components.navigation.docs.links.dependencies": "Dependencies", + "components.navigation.getInvolved.links.collabSummit": "協作者峰會", + "components.navigation.getInvolved.links.contribute": "貢獻", + "components.navigation.getInvolved.links.codeOfConduct": "管理", + "components.downloadList.links.previousReleases": "舊版", + "components.downloadList.links.packageManager": "I使用套件管理器安裝 Node.js", + "components.downloadList.links.shaSums": "發佈檔案的 SHASUM 簽名", + "components.downaloadList.links.shaSums.howToVerify": " (How to verify)", + "components.downloadList.links.allDownloads": "所有下載選項", + "components.downloadList.links.nightlyReleases": "每日建置版本", + "components.downloadList.links.unofficialBuilds": "非官方建置版本", + "components.downloadList.links.buildingFromSource": "Building Node.js from source on supported platforms", + "components.downloadList.links.installingOnLinux": "在 Linux 上使用二進位檔案安裝 Node.js", + "components.downloadList.links.installingOnWsl": "Install on Windows Subsystem for Linux (WSL)", + "components.downloadReleasesTable.changelog": "更新紀錄", + "components.downloadReleasesTable.releases": "Releases", + "components.downloadReleasesTable.docs": "文件", + "componets.header.buttons.toggleLanguage": "Toggle Language", + "components.header.buttons.toggleDarkMode": "Toggle dark/light mode", + "components.pagination.next": "下一個 | ", + "components.pagination.previous": "上一個", + "layouts.blogPost.author.byLine": "{author, select, null {} other {By {author}, }}", + "layouts.blogIndex.currentYear": "News from {year}" +} diff --git a/jsconfig.json b/jsconfig.json new file mode 100644 index 000000000000..a1e917d3bf9d --- /dev/null +++ b/jsconfig.json @@ -0,0 +1,9 @@ +{ + "compilerOptions": { + "baseUrl": ".", + "paths": { + "styles/*": ["./styles/*"], + "i18n/*": ["./i18n/*"] + } + } +} diff --git a/layouts/AboutLayout.tsx b/layouts/AboutLayout.tsx new file mode 100644 index 000000000000..ad71d5b5a67b --- /dev/null +++ b/layouts/AboutLayout.tsx @@ -0,0 +1,15 @@ +import type { PropsWithChildren } from 'react'; + +import BaseLayout from './BaseLayout'; +import SideNavigation from '../components/SideNavigation'; + +const AboutLayout = ({ children }: PropsWithChildren) => ( + +
+ +
{children}
+
+
+); + +export default AboutLayout; diff --git a/layouts/BaseLayout.tsx b/layouts/BaseLayout.tsx new file mode 100644 index 000000000000..91559745d8b2 --- /dev/null +++ b/layouts/BaseLayout.tsx @@ -0,0 +1,14 @@ +import type { PropsWithChildren } from 'react'; + +import Footer from '../components/Footer'; +import Header from '../components/Header'; + +const BaseLayout = ({ children }: PropsWithChildren) => ( + <> +
+
{children}
+