diff --git a/README.md b/README.md index 966131db576..f7b279bef48 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,111 @@ -# react.dev +# react-ko.vercel.app 리액트 공식문서 비공식 번역 사이트 -This repo contains the source code and documentation powering [react.dev](https://react.dev/). +[react.dev](https://react.dev/)를 fork하여 작성한 리파지토리입니다. +스터디그룹에서 한글 번역을 진행하고 있고, +유튜브 [FE재남](https://www.youtube.com/playlist?list=PLjQV3hketAJkh6BEl0n4PDS_2fBd0cS9v)에 스터디 영상을 공개하고 있습니다. + +## PR 작성 규칙 + +1. `develop` 브랜치를 기준으로 로컬 브랜치를 만듭니다. + _[your-own-branch-name] 부분에 원하는 이름을 넣으세요. 대괄호(`[ ]`)는 없어야 합니다._ + +```bash +/develop/> git pull origin develop +/develop/> git switch -c "[your-own-branch-name]" +``` + +2. 작업을 마치면 해당 브랜치를 `push`합니다. + +```bash +/[your-own-branch-name]/> git add . +/[your-own-branch-name]/> git commit -m "커밋메시지 자유롭게 작성" +/[your-own-branch-name]/> git push origin [your-own-branch-name] +``` + +3. 깃헙에서 `New Pull Request`를 하세요. + +- base repository: **"roy-jung/react.dev.ko"** 로 바꿔주세요. +- compare: **develop** 브랜치로 바꿔주세요. + +## 번역 규칙 + +
+

TL;DR

+ +1. 문서 제목: title 아래에 `translatedTitle: 번역제목` +2. 일반 번역: `번역내용` +3. 블록 단위 번역: `번역내용` +4. 소제목 번역: 원문과 {/...} 사이에 `번역제목` +5. 추가 코멘트: `코멘트 내용` + +
+ +1. 각 문서의 title 아래에 `translatedTitle`을 추가합니다. + +```markdown +--- +title: Scaling Up with Reducer and Context +translatedTitle: Reducer와 Context로 확장하기 +--- +``` + +2. 각 **문단** 바로 다음줄에 `번역내용`과 같이 번역글을 작성합니다. + +```markdown +Reducers let you consolidate a component's state update logic. Context lets you pass information deep down to other components. You can combine reducers and context together to manage state of a complex screen. +Reducer를 사용하면 컴포넌트의 state 업데이트 로직을 통합할 수 있습니다. Context를 사용하면 다른 컴포넌트들에 정보를 전달할 수 있습니다. Reducer와 context를 함께 사용하여 복잡한 화면의 state를 관리할 수 있습니다. +``` + +3. 목록 및 기타 블록 단위의 번역이 필요한 경우, `번역내용`와 같이 작성합니다. + +```markdown + + +- How to combine a reducer with context +- How to avoid passing state and dispatch through props +- How to keep context and state logic in a separate file + + +* reducer와 context를 결합하는 방법 +* state와 dispatch 함수를 prop으로 전달하지 않는 방법 +* context와 state 로직을 별도의 파일에서 관리하는 방법 + + + +``` + +4. 각 소제목 뒤, hash표시 앞 부분에 번역제목을 추가합니다. + +```markdown + + +### Step 1: Create the context {/_step-1-create-the-context_/} + + + +### Step 1: Create the contextContext 생성하기 {/_step-1-create-the-context_/} +``` + +5. 목록 아이템의 글이 지나치게 길어 아이템별로 바로 이어서 번역글을 작성하는 것이 가독성 측면에서 더 나은 경우 등에는 각 목록 아이템 바로 밑에 번역글을 작성합니다. + +```markdown +- **Code size:** Generally, with `useState` you have to write less code upfront. With `useReducer`, you have to write both a reducer function _and_ dispatch actions. However, `useReducer` can help cut down on the code if many event handlers modify state in a similar way. + **코드 크기:** 일반적으로 `useState`를 사용하면 미리 작성해야 하는 코드가 줄어듭니다. `useReducer`를 사용하면 reducer 함수 _와_ action을 전달하는 부분 모두 작성해야 합니다. 하지만 많은 이벤트 핸들러가 비슷한 방식으로 state를 업데이트하는 경우 `useReducer`를 사용하면 코드를 줄이는 데 도움이 될 수 있습니다. +- **Readability:** `useState` is very easy to read when the state updates are simple. When they get more complex, they can bloat your component's code and make it difficult to scan. In this case, `useReducer` lets you cleanly separate the _how_ of update logic from the _what happened_ of event handlers. + **가독성:** `useState`로 간단한 state를 업데이트 하는 경우 가독성이 좋습니다. 그렇지만 state의 구조가 더욱 복잡해지면, 컴포넌트의 코드의 양이 부풀어 오르고 한눈에 읽기 어려워질 수 있습니다. 이 경우 `useReducer`를 사용하면 업데이트 로직이 _어떻게 동작_ 하는지와 이벤트 핸들러를 통해 _무엇이 일어났는지_ 를 깔끔하게 분리할 수 있습니다. +``` + +5. 추가 코멘트(원문에 없는 내용)는 `내용`와 같이 작성합니다. + +``` + + +#### 다양한 방법으로 컴포넌트 추가하기 - @이승효 {/_다양한-방법으로-컴포넌트-추가하기---이승효_/} + +React 컴포넌트는 항상 대문자로 시작해야 하지만, 함수명이 대문자일 필요는 없습니다. **그러나 JSX 안에서 컴포넌트가 사용될 때에는 반드시 대문자로 시작해야 한다는 것에 유의하세요.** + + +``` ## Getting started @@ -15,7 +120,7 @@ This repo contains the source code and documentation powering [react.dev](https: ### Installation 1. `cd react.dev` to go into the project root -3. `yarn` to install the website's npm dependencies +2. `yarn` to install the website's npm dependencies ### Running locally @@ -38,9 +143,9 @@ The documentation is divided into several sections with a different tone and pur 1. Follow the ["Running locally"](#running-locally) instructions 1. Save the files and check in the browser - 1. Changes to React components in `src` will hot-reload - 1. Changes to markdown files in `content` will hot-reload - 1. If working with plugins, you may need to remove the `.cache` directory and restart the server +1. Changes to React components in `src` will hot-reload +1. Changes to files in `content` will hot-reload +1. If working with plugins, you may need to remove the `.cache` directory and restart the server ### Test the change @@ -60,4 +165,5 @@ The documentation is divided into several sections with a different tone and pur If you are interested in translating `react.dev`, please see the current translation efforts [here](https://github.com/reactjs/react.dev/issues/4135). ## License + Content submitted to [react.dev](https://react.dev/) is CC-BY-4.0 licensed, as found in the [LICENSE-DOCS.md](https://github.com/reactjs/react.dev/blob/main/LICENSE-DOCS.md) file. diff --git a/src/components/Layout/HomeContent.js b/src/components/Layout/HomeContent.js index a5a15ea50af..c847aa431c3 100644 --- a/src/components/Layout/HomeContent.js +++ b/src/components/Layout/HomeContent.js @@ -29,6 +29,7 @@ import CodeBlock from 'components/MDX/CodeBlock'; import {IconNavArrow} from 'components/Icon/IconNavArrow'; import {ExternalLink} from 'components/ExternalLink'; import sidebarBlog from '../../sidebarBlog.json'; +import Trans from 'components/MDX/Trans'; function Section({children, background = null}) { return ( @@ -53,7 +54,7 @@ function Section({children, background = null}) { function Header({children}) { return ( -

+

{children}

); @@ -61,7 +62,7 @@ function Header({children}) { function Para({children}) { return ( -

+

{children}

); @@ -77,7 +78,7 @@ function Left({children}) { function Center({children}) { return ( -
+
{children}
); @@ -128,10 +129,23 @@ export function HomeContent() { )} />

- React + React 한글 번역 (비공식)

+

+ + FE재남 + + 의{' '} + + [리액트 공식문서 스터디 그룹] + + 에서 번역 진행중입니다. +

+

The library for web and native user interfaces +
+ 웹과 네이티브 UI를 위한 라이브러리

-
Create user interfaces from components
+
+ Create user interfaces from components +
+ 컴포넌트로 사용자 인터페이스를 생성하세요 +
React lets you build user interfaces out of individual pieces called components. Create your own React components like{' '} Thumbnail, LikeButton, and{' '} Video. Then combine them into entire screens, pages, and apps. +
+ + React를 사용하면 컴포넌트라고 하는 개별 조각으로 사용자 + 인터페이스를 구축할 수 있습니다. 다음과 같은 자신만의 React + 컴포넌트를 만들어 보세요. Thumbnail,{' '} + LikeButton, Video와 같은 컴포넌트를 + 만듭니다. 그런 다음 전체 화면, 페이지, 앱에 결합하세요. +
@@ -173,18 +199,35 @@ export function HomeContent() { developers, using React feels the same. It is designed to let you seamlessly combine components written by independent people, teams, and organizations. +
+ + 혼자서 작업하든 수천 명의 다른 개발자와 함께 작업하든 React를 + 사용하는 느낌은 동일합니다. 독립적인 사람, 팀, 조직이 작성한 + 컴포넌트를 원활하게 결합할 수 있도록 설계되었습니다. +
-
Write components with code and markup
+
+ Write components with code and markup +
+ 코드와 마크업으로 컴포넌트를 작성하세요 +
React components are JavaScript functions. Want to show some content conditionally? Use an if statement. Displaying a list? Try array map(). Learning React is learning programming. +
+ + React 컴포넌트는 자바스크립트 함수입니다. 일부 콘텐츠를 조건부로 + 표시하고 싶으신가요? if 문을 사용하세요. 목록을 + 표시하고 싶으신가요? 배열의 map()을 사용해 보세요. + React를 배우는 것은 프로그래밍을 배우는 것입니다. +
@@ -196,18 +239,36 @@ export function HomeContent() { extension popularized by React. Putting JSX markup close to related rendering logic makes React components easy to create, maintain, and delete. +
+ + 이 마크업 구문을 JSX라고 합니다. 이는 React에서 대중화된 + JavaScript 구문 확장입니다. JSX 마크업을 관련 렌더링 로직에 + 가깝게 배치하면 React 컴포넌트를 쉽게 생성, 유지, 삭제할 수 + 있습니다. +
-
Add interactivity wherever you need it
+
+ Add interactivity wherever you need it +
+ 어디서든 상호작용을 추가하세요 +
React components receive data and return what should appear on the screen. You can pass them new data in response to an interaction, like when the user types into an input. React will then update the screen to match the new data. +
+ + 리액트 컴포넌트는 데이터를 수신하고 화면에 표시되어야 할 내용을 + 화면으로 반환합니다. 상호작용에 대한 응답으로 새로운 데이터를 + 전달할 수 있습니다, 새로운 데이터를 전달할 수 있습니다. 그러면 + React는 새로운 데이터와 일치하도록 화면을 업데이트합니다. +
@@ -218,6 +279,12 @@ export function HomeContent() { You don’t have to build your whole page in React. Add React to your existing HTML page, and render interactive React components anywhere on it. +
+ + 전체 페이지를 React로 빌드할 필요는 없습니다. 기존 HTML 페이지에 + React를 추가하고 페이지의 어느 곳에서나 대화형 React 컴포넌트를 + 렌더링하세요. +
- Go full-stack
- with a framework + Go full-stack with a framework +
+ 프레임워크로 풀스택 하세요
React is a library. It lets you put components together, but it @@ -242,6 +310,14 @@ export function HomeContent() { entire app with React, we recommend a full-stack React framework like Next.js or{' '} Remix. +
+ + React는 라이브러리입니다. 컴포넌트를 조합할 수는 있지만 라우팅 + 및 데이터 불러오기 방법을 규정하지는 않습니다. React로 전체 앱을 + 빌드하려면 Next.js나 + Remix와 같은 풀스택 React + 프레임워크를 사용하는 것이 좋습니다. +
@@ -253,6 +329,13 @@ export function HomeContent() { you fetch data in asynchronous components that run on the server or even during the build. Read data from a file or a database, and pass it down to your interactive components. +
+ + React는 또한 아키텍처입니다. 이를 구현하는 프레임워크를 사용하면 + 서버에서 실행되는 비동기 컴포넌트에서 또는 빌드 도중에도 + 데이터를 가져올 수 있습니다. 파일이나 데이터베이스에서 데이터를 + 읽어와 인터랙티브한 컴포넌트에 전달할 수 있습니다. +
-
Use the best from every platform
+
+ Use the best from every platform +
+ 모든 플랫폼에서 최고를 사용하세요 +
People love web and native apps for different reasons. React lets you build both web apps and native apps using the same skills. It leans upon each platform’s unique strengths to let your interfaces feel just right on every platform. +
+ + 사람들은 각기 다른 이유로 웹 앱과 네이티브 앱을 선호합니다. + React를 사용하면 동일한 기술을 사용하여 웹 앱과 네이티브 앱을 + 모두 빌드할 수 있습니다. 각 플랫폼의 고유한 강점을 활용하여 + 모든 플랫폼에서 인터페이스를 똑같이 느낄 수 있습니다. +
@@ -287,6 +381,8 @@ export function HomeContent() {

Stay true to the web +
+ 웹에 충실합니다

People expect web app pages to load fast. On the server, @@ -295,6 +391,15 @@ export function HomeContent() { content before any JavaScript code loads. On the client, React can use standard web APIs to keep your UI responsive even in the middle of rendering. +
+ + 사람들은 웹 앱 페이지가 빠르게 로드되기를 기대합니다. + 서버에서 React를 사용하면 데이터를 가져오는 동안 HTML + 스트리밍을 시작하여 JavaScript 코드가 로드되기 전에 + 나머지 콘텐츠를 점진적으로 채울 수 있습니다. + 클라이언트에서 React는 표준 웹 API를 사용해 렌더링 + 도중에도 UI의 반응성을 유지할 수 있습니다. +

@@ -373,6 +478,8 @@ export function HomeContent() {

Go truly native +
+ 진정한 네이티브 앱

People expect native apps to look and feel like their @@ -387,6 +494,23 @@ export function HomeContent() { are truly native. It’s not a web view—your React components render real Android and iOS views provided by the platform. +
+ + 사람들은 네이티브 앱이 해당 플랫폼과 같은 모양과 + 느낌을 주기를 기대합니다.{' '} + + React Native + {' '} + 와{' '} + + Expo + {' '} + 를 사용하면 Android, iOS 등을 위한 앱을 React로 + 빌드할 수 있습니다. UI가 네이티브이기 때문에 + 네이티브처럼 보이고 느껴집니다. 웹 뷰가 아니라 + 플랫폼에서 제공하는 실제 Android 및 iOS 뷰를 React + 컴포넌트가 렌더링합니다. +

@@ -400,6 +524,13 @@ export function HomeContent() { team can ship to many platforms without sacrificing the user experience. Your organization can bridge the platform silos, and form teams that own entire features end-to-end. +
+ + React를 사용하면 웹 및 네이티브 개발자가 될 수 있습니다. + 사용자 경험의 저하 없이 다양한 플랫폼에 배포할 수 있습니다. + 조직은 플랫폼의 경계를 극복하고 전체 기능을 온전히 소유하는 + 팀을 구성할 수 있습니다. +
@@ -414,12 +545,23 @@ export function HomeContent() {
-
Upgrade when the future is ready
+
+ Upgrade when the future is ready +
+ 준비된 미래에 업그레이드하세요 +
React approaches changes with care. Every React commit is tested on business-critical surfaces with over a billion users. Over 100,000 React components at Meta help validate every migration strategy. +
+ + React는 변화에 신중하게 접근합니다. 모든 React 커밋은 10억 + 명 이상의 사용자가 있는 비즈니스 크리티컬한 환경에서 + 테스트됩니다. Meta의 100,000개 이상의 React 컴포넌트는 모든 + 마이그레이션 전략을 검증하는 데 도움이 됩니다. +
@@ -427,6 +569,14 @@ export function HomeContent() { Some research takes years to pay off. React has a high bar for taking a research idea into production. Only proven approaches become a part of React. +
+ + React 팀은 항상 React를 개선하는 방법을 연구하고 있습니다. + 어떤 연구는 결실을 맺기까지 몇 년이 걸리기도 합니다. + React는 연구 아이디어를 프로덕션에 적용하기 위한 높은 + 기준을 가지고 있습니다. 검증된 접근 방식만이 React의 + 일부가 됩니다. +
@@ -469,13 +619,20 @@ export function HomeContent() {
- Join a community
- of millions + Join a community of millions +
+ 수백만 명의 커뮤니티에 참여하세요
You’re not alone. Two million developers from all over the world visit the React docs every month. React is something that people and teams can agree on. +
+ + 여러분은 혼자가 아닙니다. 전 세계 200만 명의 개발자가 매달 + React 문서를 방문합니다. React는 모든 사람과 팀이 동의할 수 + 있는 것입니다. +
@@ -490,6 +647,16 @@ export function HomeContent() { beginners and experts, researchers and artists, teachers and students. Our backgrounds may be very different, but React lets us all create user interfaces together. +
+ + 이것이 바로 React가 라이브러리, 아키텍처, 심지어 에코시스템 + 그 이상인 이유입니다. React는 커뮤니티입니다. 도움을 + 요청하고, 기회를 찾고, 새로운 친구를 만날 수 있는 곳입니다. + 개발자와 디자이너, 초보자와 전문가, 연구자와 아티스트, + 교사와 학생을 모두 만날 수 있습니다. 우리 모두의 배경은 매우 + 다를 수 있지만, React를 사용하면 모두 함께 사용자 + 인터페이스를 만들 수 있습니다. +
diff --git a/src/components/Layout/Page.tsx b/src/components/Layout/Page.tsx index 48d60dde634..32973043ef7 100644 --- a/src/components/Layout/Page.tsx +++ b/src/components/Layout/Page.tsx @@ -28,7 +28,7 @@ interface PageProps { children: React.ReactNode; toc: Array; routeTree: RouteItem; - meta: {title?: string; description?: string}; + meta: {title?: string; description?: string; translatedTitle?: string}; section: 'learn' | 'reference' | 'community' | 'blog' | 'home' | 'unknown'; } @@ -40,6 +40,7 @@ export function Page({children, toc, routeTree, meta, section}: PageProps) { routeTree ); const title = meta.title || route?.title || ''; + const translatedTitle = meta.translatedTitle || undefined; const description = meta.description || route?.description || ''; const isHomePage = cleanedPath === '/'; const isBlogIndex = cleanedPath === '/blog'; @@ -56,6 +57,7 @@ export function Page({children, toc, routeTree, meta, section}: PageProps) { )}> diff --git a/src/components/Layout/Sidebar/SidebarButton.tsx b/src/components/Layout/Sidebar/SidebarButton.tsx index b1276cdb828..83eed6c9f60 100644 --- a/src/components/Layout/Sidebar/SidebarButton.tsx +++ b/src/components/Layout/Sidebar/SidebarButton.tsx @@ -5,9 +5,11 @@ import * as React from 'react'; import cn from 'classnames'; import {IconNavArrow} from 'components/Icon/IconNavArrow'; +import Trans from 'components/MDX/Trans'; interface SidebarButtonProps { title: string; + translatedTitle?: string; heading: boolean; level: number; onClick: (event: React.MouseEvent) => void; @@ -17,6 +19,7 @@ interface SidebarButtonProps { export function SidebarButton({ title, + translatedTitle, heading, level, onClick, @@ -46,6 +49,12 @@ export function SidebarButton({ )} onClick={onClick}> {title} + {!!translatedTitle && ( + <> +
+ {translatedTitle} + + )} {typeof isExpanded && !heading && ( diff --git a/src/components/Layout/Sidebar/SidebarLink.tsx b/src/components/Layout/Sidebar/SidebarLink.tsx index 0d69b30be58..8eccf17a81a 100644 --- a/src/components/Layout/Sidebar/SidebarLink.tsx +++ b/src/components/Layout/Sidebar/SidebarLink.tsx @@ -9,11 +9,13 @@ import * as React from 'react'; import cn from 'classnames'; import {IconNavArrow} from 'components/Icon/IconNavArrow'; import Link from 'next/link'; +import Trans from 'components/MDX/Trans'; interface SidebarLinkProps { href: string; selected?: boolean; title: string; + translatedTitle?: string; level: number; wip: boolean | undefined; icon?: React.ReactNode; @@ -27,6 +29,7 @@ export function SidebarLink({ href, selected = false, title, + translatedTitle, wip, level, isExpanded, @@ -77,7 +80,13 @@ export function SidebarLink({ className={cn({ 'text-gray-400 dark:text-gray-500': wip, })}> - {title} + {title}{' '} + {!!translatedTitle && ( + <> +
+ {translatedTitle} + + )}
{isExpanded != null && !hideArrow && ( {currentRoutes.map( ( - {path, title, routes, wip, heading, hasSectionHeader, sectionHeader}, + { + path, + title, + translatedTitle, + routes, + wip, + heading, + hasSectionHeader, + sectionHeader, + }, index ) => { const selected = slug === path; @@ -112,6 +121,7 @@ export function SidebarRouteTree({ selected={selected} level={level} title={title} + translatedTitle={translatedTitle} wip={wip} isExpanded={isExpanded} isBreadcrumb={isBreadcrumb} @@ -137,6 +147,7 @@ export function SidebarRouteTree({ selected={selected} level={level} title={title} + translatedTitle={translatedTitle} wip={wip} /> diff --git a/src/components/Layout/getRouteMeta.tsx b/src/components/Layout/getRouteMeta.tsx index cb7938cfd82..c40b0938ee2 100644 --- a/src/components/Layout/getRouteMeta.tsx +++ b/src/components/Layout/getRouteMeta.tsx @@ -19,6 +19,7 @@ export type RouteTag = export interface RouteItem { /** Page title (for the sidebar) */ title: string; + translatedTitle?: string; /** Optional page description for heading */ description?: string; /* Additional meta info for page tagging */ diff --git a/src/components/Layout/useTocHighlight.tsx b/src/components/Layout/useTocHighlight.tsx index 544396c68b7..6696e7a1bc5 100644 --- a/src/components/Layout/useTocHighlight.tsx +++ b/src/components/Layout/useTocHighlight.tsx @@ -6,14 +6,15 @@ import {useState, useRef, useEffect} from 'react'; const TOP_OFFSET = 85; -export function getHeaderAnchors(): HTMLAnchorElement[] { +export function getHeaders(): HTMLHeadingElement[] { return Array.prototype.filter.call( - document.getElementsByClassName('mdx-header-anchor'), + document.getElementsByClassName('mdx-heading'), function (testElement) { return ( - testElement.parentNode.nodeName === 'H1' || - testElement.parentNode.nodeName === 'H2' || - testElement.parentNode.nodeName === 'H3' + (testElement.nodeName === 'H1' || + testElement.nodeName === 'H2' || + testElement.nodeName === 'H3') && + !!testElement.querySelector('.mdx-header-anchor') ); } ); @@ -30,18 +31,18 @@ export function useTocHighlight() { function updateActiveLink() { const pageHeight = document.body.scrollHeight; const scrollPosition = window.scrollY + window.innerHeight; - const headersAnchors = getHeaderAnchors(); + const headers = getHeaders(); if (scrollPosition >= 0 && pageHeight - scrollPosition <= 0) { // Scrolled to bottom of page. - setCurrentIndex(headersAnchors.length - 1); + setCurrentIndex(headers.length - 1); return; } let index = -1; - while (index < headersAnchors.length - 1) { - const headerAnchor = headersAnchors[index + 1]; - const {top} = headerAnchor.getBoundingClientRect(); + while (index < headers.length - 1) { + const header = headers[index + 1]; + const {top} = header.getBoundingClientRect(); if (top >= TOP_OFFSET) { break; diff --git a/src/components/MDX/Challenges/Challenge.tsx b/src/components/MDX/Challenges/Challenge.tsx index 24e99541cc3..b8966a454b3 100644 --- a/src/components/MDX/Challenges/Challenge.tsx +++ b/src/components/MDX/Challenges/Challenge.tsx @@ -23,6 +23,7 @@ export function Challenge({ isRecipes, totalChallenges, currentChallenge, + currentChallenge: {name, order}, hasNextChallenge, handleClickNextChallenge, }: ChallengeProps) { @@ -43,18 +44,24 @@ export function Challenge({ setShowSolution((solution) => !solution); }; + const prefix = `${ + isRecipes ? 'Example' : 'Challenge' + } ${order} of ${totalChallenges}`; + let newName; + if (Array.isArray(name)) { + newName = [...name]; + newName[0] = `${prefix}: ${newName[0]}`; + } else { + newName = `${prefix}: ${name}`; + } + return (

-
- {isRecipes ? 'Example' : 'Challenge'} {currentChallenge.order} of{' '} - {totalChallenges} - : -
- {currentChallenge.name} + {newName}

{currentChallenge.content}
diff --git a/src/components/MDX/Challenges/Challenges.tsx b/src/components/MDX/Challenges/Challenges.tsx index 661269f0ede..8ac78473532 100644 --- a/src/components/MDX/Challenges/Challenges.tsx +++ b/src/components/MDX/Challenges/Challenges.tsx @@ -10,6 +10,7 @@ import {H4} from 'components/MDX/Heading'; import {Challenge} from './Challenge'; import {Navigation} from './Navigation'; import {useRouter} from 'next/router'; +import Trans from '../Trans'; interface ChallengesProps { children: React.ReactElement[]; @@ -133,6 +134,7 @@ export function Challenges({ : 'text-3xl text-link' )}> {titleText} + {isRecipes ? '예제를 풀어보세요' : '도전 과제'} )} {totalChallenges > 1 && ( diff --git a/src/components/MDX/Challenges/Navigation.tsx b/src/components/MDX/Challenges/Navigation.tsx index e448828cfbb..a9b2d539b54 100644 --- a/src/components/MDX/Challenges/Navigation.tsx +++ b/src/components/MDX/Challenges/Navigation.tsx @@ -87,7 +87,8 @@ export function Navigation({ {challenges.map(({name, id, order}, index) => (