diff --git a/docs/intro.md b/docs/intro.md deleted file mode 100644 index 45e8604..0000000 --- a/docs/intro.md +++ /dev/null @@ -1,47 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Tutorial Intro - -Let's discover **Docusaurus in less than 5 minutes**. - -## Getting Started - -Get started by **creating a new site**. - -Or **try Docusaurus immediately** with **[docusaurus.new](https://docusaurus.new)**. - -### What you'll need - -- [Node.js](https://nodejs.org/en/download/) version 18.0 or above: - - When installing Node.js, you are recommended to check all checkboxes related to dependencies. - -## Generate a new site - -Generate a new Docusaurus site using the **classic template**. - -The classic template will automatically be added to your project after you run the command: - -```bash -npm init docusaurus@latest my-website classic -``` - -You can type this command into Command Prompt, Powershell, Terminal, or any other integrated terminal of your code editor. - -The command also installs all necessary dependencies you need to run Docusaurus. - -## Start your site - -Run the development server: - -```bash -cd my-website -npm run start -``` - -The `cd` command changes the directory you're working with. In order to work with your newly created Docusaurus site, you'll need to navigate the terminal there. - -The `npm run start` command builds your website locally and serves it through a development server, ready for you to view at http://localhost:3000/. - -Open `docs/intro.md` (this page) and edit some lines: the site **reloads automatically** and displays your changes. diff --git a/docs/javascript/base/02-variables.md b/docs/javascript/base/02-variables.md index 98718a7..20a5d5e 100644 --- a/docs/javascript/base/02-variables.md +++ b/docs/javascript/base/02-variables.md @@ -8,9 +8,9 @@ sidebar_position: 2 Можно объявить при помощи: -- let -- const (константа, т.е. изменению не подлежит) -- var (устаревший способ, подробности позже) +- **let** +- **const** (константа, т.е. изменению не подлежит) +- **var** (устаревший способ, подробности позже) ```js let message; @@ -33,15 +33,15 @@ message = 'Hello'; Всего существует 8 типов данных: -- number для целых и вещественных чисел, -- bigint для работы с целыми числами произвольной длины, -- string для строк, -- boolean для логических значений истинности или ложности: true/false, -- null – тип с единственным значением null, т.е. «пустое значение» или «значение не существует», -- undefined – тип с единственным значением undefined, т.е. «значение не задано», -- object и symbol – сложные структуры данных и уникальные идентификаторы; их мы ещё не изучили. +- **number** для целых и вещественных чисел, +- **bigint** для работы с целыми числами произвольной длины, +- **string** для строк, +- **boolean** для логических значений истинности или ложности: true/false, +- **null** – тип с единственным значением null, т.е. «пустое значение» или «значение не существует», +- **undefined** – тип с единственным значением undefined, т.е. «значение не задано», +- **object** и **symbol** – сложные структуры данных и уникальные идентификаторы; их мы ещё не изучили. -Оператор typeof возвращает тип значения переменной, с двумя исключениями: +Оператор `typeof` возвращает тип значения переменной, с двумя исключениями: ```js typeof null == "object" // ошибка в языке diff --git a/docs/javascript/base/05-compare-ops.md b/docs/javascript/base/05-compare-ops.md index c2ef0af..e8c3ab8 100644 --- a/docs/javascript/base/05-compare-ops.md +++ b/docs/javascript/base/05-compare-ops.md @@ -23,14 +23,14 @@ sidebar_position: 5 - Если обе строки заканчиваются одновременно, то они равны. Иначе, большей считается более длинная строка. ## Сравнение разных типов -Использование обычного сравнения **==** может вызывать проблемы. -Это происходит из-за того, что операнды разных типов преобразуются оператором **==** к числу. В итоге, и пустая строка, и false становятся нулём. +Использование обычного сравнения `==` может вызывать проблемы. +Это происходит из-за того, что операнды разных типов преобразуются оператором `==` к числу. В итоге, и пустая строка, и false становятся нулём. -**Оператор строгого равенства === проверяет равенство без приведения типов.** +**Оператор строгого равенства `===` проверяет равенство без приведения типов.** ## Сравнение с null и undefined -Поведение **null** и **undefined** при сравнении с другими значениями — особое: +Поведение `null` и `undefined` при сравнении с другими значениями — особое: При строгом равенстве **===** \ Эти значения различны, так как различны их типы. @@ -39,5 +39,5 @@ sidebar_position: 5 Эти значения равны друг другу и не равны никаким другим значениям. Это специальное правило языка. При использовании математических операторов и других операторов сравнения \< \> \<= \>= -Значения null/undefined преобразуются к числам: **null** становится 0, а **undefined** – NaN. +Значения null/undefined преобразуются к числам: `null` становится 0, а `undefined` – NaN. diff --git a/docs/javascript/base/06-conditions-logic.md b/docs/javascript/base/06-conditions-logic.md index 4e86f4b..3618121 100644 --- a/docs/javascript/base/06-conditions-logic.md +++ b/docs/javascript/base/06-conditions-logic.md @@ -64,7 +64,7 @@ let result = условие ? значение1 : значение2; ```js a ||= b; ``` -Оператор **||=** принимает два операнда и выполняет следующие действия: +Оператор `||=` принимает два операнда и выполняет следующие действия: - Вычисляет операнды слева направо. - Конвертирует ***a*** в логическое значение. @@ -81,7 +81,7 @@ a ||= b; ```js result = value1 && value2 && value3; ``` -Оператор **&&** выполняет следующие действия: +Оператор `&&` выполняет следующие действия: - Вычисляет операнды слева направо. - Каждый операнд преобразует в логическое значение. Если результат **false**, останавливается и возвращает исходное diff --git a/docs/javascript/base/08-garbage-collector.md b/docs/javascript/base/08-garbage-collector.md new file mode 100644 index 0000000..a45fb51 --- /dev/null +++ b/docs/javascript/base/08-garbage-collector.md @@ -0,0 +1,53 @@ +--- +sidebar_position: 8 +--- + + +# Сборка мусора + +Управление памятью в JavaScript выполняется автоматически и незаметно. Мы создаём примитивы, объекты, функции… Всё это занимает память. + +### Достижимость +Основной концепцией управления памятью в JavaScript является принцип достижимости. + +Если упростить, то «достижимые» значения – это те, которые доступны или используются. Они гарантированно находятся в памяти. + +1. Существует базовое множество достижимых значений, которые не могут быть удалены. + + Например: + + - Выполняемая в данный момент функция, её локальные переменные и параметры. + - Другие функции в текущей цепочке вложенных вызовов, их локальные переменные и параметры. + - Глобальные переменные. + - (некоторые другие внутренние значения) + Эти значения мы будем называть корнями. + +2. Любое другое значение считается достижимым, если оно доступно из корня по ссылке или по цепочке ссылок. + + Например, если в глобальной переменной есть объект, и он имеет свойство, в котором хранится ссылка на другой объект, то этот объект считается достижимым. И те, на которые он ссылается, тоже достижимы. + +### Внутренние алгоритмы +Основной алгоритм сборки мусора называется «алгоритм пометок» (от англ. «mark-and-sweep»). + +Согласно этому алгоритму, сборщик мусора регулярно выполняет следующие шаги: + +- Сборщик мусора «помечает» (запоминает) все корневые объекты. +- Затем он идёт по ним и «помечает» все ссылки из них. +- Затем он идёт по отмеченным объектам и отмечает их ссылки. Все посещённые объекты запоминаются, чтобы в будущем не посещать один и тот же объект дважды. +- …И так далее, пока не будут посещены все достижимые (из корней) ссылки. +- Все непомеченные объекты удаляются. + +Движки JavaScript применяют множество оптимизаций, чтобы она работала быстрее и не задерживала выполнение кода. + +Вот некоторые из оптимизаций: + +- **Сборка по поколениям (Generational collection)** – объекты делятся на два набора: «новые» и «старые». В типичном коде многие объекты имеют короткую жизнь: они появляются, выполняют свою работу и быстро умирают, так что имеет смысл отслеживать новые объекты и, если это так, быстро очищать от них память. Те, которые выживают достаточно долго, становятся «старыми» и проверяются реже. +- **Инкрементальная сборка (Incremental collection)** – если объектов много, и мы пытаемся обойти и пометить весь набор объектов сразу, это может занять некоторое время и привести к видимым задержкам в выполнении скрипта. Так что движок делит всё множество объектов на части, и далее очищает их одну за другой. Получается несколько небольших сборок мусора вместо одной всеобщей. Это требует дополнительного учёта для отслеживания изменений между частями, но зато получается много крошечных задержек вместо одной большой. +- **Сборка в свободное время (Idle-time collection)** – чтобы уменьшить возможное влияние на производительность, сборщик мусора старается работать только во время простоя процессора. + +Существуют и другие способы оптимизации и разновидности алгоритмов сборки мусора, потому что разные движки реализуют разные хитрости и методы. + +### Главное, что нужно знать: +- Сборка мусора выполняется автоматически. Мы не можем ускорить или предотвратить её. +- Объекты сохраняются в памяти, пока они достижимы. +- Если на объект есть ссылка – вовсе не факт, что он является достижимым (из корня): набор взаимосвязанных объектов может стать недоступен в целом. \ No newline at end of file diff --git a/docs/javascript/data-types/01-primitive-methods.md b/docs/javascript/data-types/01-primitive-methods.md new file mode 100644 index 0000000..bb71bc8 --- /dev/null +++ b/docs/javascript/data-types/01-primitive-methods.md @@ -0,0 +1,17 @@ +--- +sidebar_position: 1 +--- + +# Методы примитивов +Ключевые различия между примитивами и объектами. + +#### Примитив + +- Это – значение «примитивного» типа. +- Есть 7 примитивных типов: string, number, boolean, symbol, null, undefined и bigint. + +#### Объект + +- Может хранить множество значений как свойства. +- Объявляется при помощи фигурных скобок \{\}, например: \{name: "Рома", age: 30\}. В JavaScript есть и другие виды объектов: например, функции тоже являются объектами. + diff --git a/docs/javascript/data-types/index.md b/docs/javascript/data-types/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/javascript/objects/01-intro.md b/docs/javascript/objects/01-intro.md index fdc3259..bb47db7 100644 --- a/docs/javascript/objects/01-intro.md +++ b/docs/javascript/objects/01-intro.md @@ -87,7 +87,7 @@ alert(obj.__proto__); // [object Object], значение - это объект В отличие от многих других языков, особенность JavaScript-объектов в том, что можно получить доступ к любому свойству. Даже если свойства не существует – ошибки не будет! -При обращении к свойству, которого нет, возвращается undefined. Это позволяет просто проверить существование свойства: +При обращении к свойству, которого нет, возвращается **undefined**. Это позволяет просто проверить существование свойства: ```js let user = {}; diff --git a/docs/javascript/objects/02-copying-objects.md b/docs/javascript/objects/02-copying-objects.md new file mode 100644 index 0000000..319f84c --- /dev/null +++ b/docs/javascript/objects/02-copying-objects.md @@ -0,0 +1,76 @@ +--- +sidebar_position: 2 +--- + +# Копирование объектов и ссылки + +💥 ***При копировании переменной объекта копируется ссылка, но сам объект не дублируется.*** +```js +let user = { name: 'John' }; + +let admin = user; + +admin.name = 'Pete'; // изменено по ссылке из переменной "admin" + +alert(user.name); // 'Pete', изменения видны по ссылке из переменной "user" +``` + +## Сравнение по ссылке +Два объекта равны только в том случае, если это один и тот же объект. + +***a*** и ***b*** ссылаются на один и тот же объект, поэтому они равны: +```js +let a = {}; +let b = a; // копирование по ссылке + +alert( a == b ); // true, обе переменные ссылаются на один и тот же объект +alert( a === b ); // true +``` + +Здесь два независимых объекта не равны, даже если они выглядят одинаково (оба пусты): +```js +let a = {}; +let b = {}; // два независимых объекта + +alert( a == b ); // false +``` + +## Клонирование и объединение, Object.assign +Есть 2 вида копирования shallow - поверхностное и deep - глубокое + +#### Перебор всех свойств объекта через цикл или рекурсию (shallow / deep) +```js +let user = { + name: "John", + age: 30 +}; + +let clone = {}; // новый пустой объект + +// давайте скопируем все свойства user в него +for (let key in user) { + clone[key] = user[key]; +} + +// теперь clone это полностью независимый объект с тем же содержимым +clone.name = "Pete"; // изменим в нём данные + +alert( user.name ); // все ещё John в первоначальном объекте +``` +Готовая реализация, через например _.cloneDeep(obj) из библиотеки JavaScript lodash. + +#### Метод Object.assign (shallow) +```js +Object.assign(dest, [src1, src2, src3...]) +``` +#### Оператор расширения \{...obj\} (shallow) +Метод тоже делает поверхностное копирование, для глубокого надо обойти объект рекурсивно + +#### JsonParse (deep) +Cамый простой способ скопировать объект со всеми уровнями вложенности, не копирует методы: +```js +let clone = JSON.parse(JSON.stringify(obj)) +``` + +#### Метод structuredClone (deep) +Мы можем использовать глобальный метод ***structuredClone()***, который позволяет сделать полную копию объекта. К сожалению он поддерживается только современными браузерами. diff --git a/docs/javascript/objects/03-methods-this.md b/docs/javascript/objects/03-methods-this.md new file mode 100644 index 0000000..72fe70f --- /dev/null +++ b/docs/javascript/objects/03-methods-this.md @@ -0,0 +1,40 @@ +--- +sidebar_position: 3 +--- + +# Методы объекта, "this" + +***Для доступа к информации внутри объекта метод может использовать ключевое слово this.*** +```js +let user = { + name: "John", + + sayHi() { + alert(this.name); // "this" - это "текущий объект". + } +}; +``` +### «this» не является фиксированным +В JavaScript ключевое слово «this» ведёт себя иначе, чем в большинстве других языков программирования. Его можно использовать в любой функции, даже если это не метод объекта. + +❗ ***Вызов без объекта: this == undefined*** + +В строгом режиме ("use strict") в таком коде значением `this` будет являться `undefined`. Если мы попытаемся получить доступ к this.name – это вызовет ошибку. + +В нестрогом режиме значением `this` в таком случае будет глобальный объект (`window` в браузерe, мы вернёмся к этому позже в главе Глобальный объект). Это – исторически сложившееся поведение `this`, которое исправляется использованием строгого режима ("use strict"). + +Обычно подобный вызов является ошибкой программирования. Если внутри функции используется this, тогда она ожидает, что будет вызвана в контексте какого-либо объекта. + +❗ ***Последствия свободного this*** + +В JavaScript `this` является «свободным», его значение вычисляется в момент вызова метода и не зависит от того, где этот метод был объявлен, а скорее от того, какой объект вызывает метод (какой объект стоит «перед точкой»). + +Эта концепция вычисления `this` в момент исполнения имеет как свои плюсы, так и минусы. С одной стороны, функция может быть повторно использована в качестве метода у различных объектов (что повышает гибкость). + +### У стрелочных функций нет «this» +Стрелочные функции особенные: у них нет своего «собственного» `this`. Если мы ссылаемся на `this` внутри такой функции, то оно берётся из внешней «нормальной» функции. + +1. Методы могут ссылаться на объект через `this`. +2. Значение `this` определяется во время исполнения кода. + - При объявлении любой функции в ней можно использовать `this`, но этот `this` не имеет значения до тех пор, пока функция не будет вызвана. + - Когда функция вызывается синтаксисом «метода» – ***object.method()***, значением `this` во время вызова является `object`. \ No newline at end of file diff --git a/docs/javascript/objects/04-constructor-new-op.md b/docs/javascript/objects/04-constructor-new-op.md new file mode 100644 index 0000000..b005530 --- /dev/null +++ b/docs/javascript/objects/04-constructor-new-op.md @@ -0,0 +1,34 @@ +--- +sidebar_position: 4 +--- + +# Конструктор, оператор "new" + +### Функция-конструктор +Функции-конструкторы технически являются обычными функциями. Но есть два соглашения: + +1. Имя функции-конструктора должно начинаться с большой буквы. +2. Функция-конструктор должна выполняться только с помощью оператора "new". + + +Когда функция вызывается как new User(...), происходит следующее: + +1. Создаётся новый пустой объект, и он присваивается `this`. +2. Выполняется тело функции. Обычно оно модифицирует `this`, добавляя туда новые свойства. +3. Возвращается значение `this`. + +Другими словами, new User(...) делает что-то вроде: +```js +function User(name) { + // this = {}; (неявно) + + // добавляет свойства к this + this.name = name; + this.isAdmin = false; + + // return this; (неявно) +} +``` +Итого: +- Функции-конструкторы или просто конструкторы, являются обычными функциями, но существует общепринятое соглашение именовать их с заглавной буквы. +- Функции-конструкторы следует вызывать только с помощью `new`. Такой вызов подразумевает создание пустого `this` в начале и возврат заполненного в конце. \ No newline at end of file diff --git a/docs/javascript/objects/05-option-chaining.md b/docs/javascript/objects/05-option-chaining.md new file mode 100644 index 0000000..3ab6199 --- /dev/null +++ b/docs/javascript/objects/05-option-chaining.md @@ -0,0 +1,36 @@ +--- +sidebar_position: 5 +--- + +# Опциональная цепочка '?.' +Опциональная цепочка ?. останавливает вычисление и возвращает `undefined`, если значение перед ?. равно `undefined` или `null`. +```js +let user = {}; // пользователь без адреса + +alert( user?.address?.street ); // undefined (без ошибки) +``` +### Другие варианты применения: ?.(), ?.[] +Опциональная цепочка ?. — это не оператор, а специальная синтаксическая конструкция, которая также работает с функциями и квадратными скобками. + +Например, ?.() используется для вызова функции, которая может не существовать. + +❗ ***Мы можем использовать ?. для безопасного чтения и удаления, но не для записи*** + +Опциональная цепочка ?. не имеет смысла в левой части присваивания. +```js +let user = null; + +user?.name = "John"; // Ошибка, не работает +// то же самое что написать undefined = "John" +``` + +## Итого +Синтаксис опциональной цепочки ?. имеет три формы: + +1. **obj?.prop** – возвращает ***obj.prop*** если `obj` существует, в противном случае `undefined`. +2. **obj?.[prop]** – возвращает ***obj[prop]*** если `obj` существует, в противном случае `undefined`. +3. **obj.method?.()** – вызывает ***obj.method()***, если obj.method существует, в противном случае возвращает `undefined`. + +Как мы видим, все они просты и понятны в использовании. ?. проверяет левую часть на `null/undefined` и позволяет продолжить вычисление, если это не так. + +Цепочка ?. позволяет безопасно получать доступ к вложенным свойствам. \ No newline at end of file diff --git a/docs/javascript/objects/06-symbol.md b/docs/javascript/objects/06-symbol.md new file mode 100644 index 0000000..1ec0400 --- /dev/null +++ b/docs/javascript/objects/06-symbol.md @@ -0,0 +1,44 @@ +--- +sidebar_position: 6 +--- + +# Тип данных Symbol + +Символ (symbol) – примитивный тип данных, использующийся для создания уникальных идентификаторов. + +```js +// Создаём новый символ - id +let id = Symbol(); +``` + +При создании, символу можно дать описание (также называемое имя), в основном использующееся для отладки кода + +Символы гарантированно уникальны. Даже если мы создадим множество символов с одинаковым описанием, это всё равно будут +разные символы. Описание – это просто метка, которая ни на что не влияет. + +```js +let id1 = Symbol("id"); +let id2 = Symbol("id"); + +alert(id1 == id2); // false +``` + +💥***Символы не преобразуются автоматически в строки*** + +#### Символы игнорируются циклом for…in + +Свойства, чьи ключи – символы, не перебираются циклом for..in. + +Символы имеют два основных варианта использования: + +1. «Скрытые» свойства объектов. + Если мы хотим добавить свойство в объект, который «принадлежит» другому скрипту или библиотеке, мы можем создать + символ и использовать его в качестве ключа. Символьное свойство не появится в for..in, так что оно не будет нечаянно + обработано вместе с другими. Также оно не будет модифицировано прямым обращением, так как другой скрипт не знает о + нашем символе. Таким образом, свойство будет защищено от случайной перезаписи или использования. + + Так что, используя символьные свойства, мы можем спрятать что-то нужное нам, но что другие видеть не должны. +2. Существует множество системных символов, используемых внутри JavaScript, доступных как Symbol.*. Мы можем + использовать их, чтобы изменять встроенное поведение ряда объектов. Например, в дальнейших главах мы будем + использовать Symbol.iterator для итераторов, Symbol.toPrimitive для настройки преобразования объектов в примитивы и + так далее. \ No newline at end of file diff --git a/docs/javascript/objects/07-objects-to-primitives.md b/docs/javascript/objects/07-objects-to-primitives.md new file mode 100644 index 0000000..3c1ceb3 --- /dev/null +++ b/docs/javascript/objects/07-objects-to-primitives.md @@ -0,0 +1,27 @@ +--- +sidebar_position: 7 +--- + +# Преобразование объектов в примитивы + +Преобразование объекта в примитив вызывается автоматически многими встроенными функциями и операторами, которые ожидают примитив в качестве значения. + +Существует всего 3 типа (хинта) для этого: + +- "string" (для alert и других операций, которым нужна строка) +- "number" (для математических операций) +- "default" (для некоторых других операторов, обычно объекты реализуют его как "number") + +Спецификация явно описывает для каждого оператора, какой ему следует использовать хинт. + +Алгоритм преобразования таков: + +1. Сначала вызывается метод obj[Symbol.toPrimitive](hint), если он существует, +2. В случае, если хинт равен "string" + - происходит попытка вызвать obj.toString() и obj.valueOf(), смотря что есть. +3. В случае, если хинт равен "number" или "default" + - происходит попытка вызвать obj.valueOf() и obj.toString(), смотря что есть. + +Все эти методы должны возвращать примитив (если определены). + +На практике часто бывает достаточно реализовать только obj.toString() в качестве универсального метода для преобразований к строке, который должен возвращать удобочитаемое представление объекта для целей логирования или отладки. \ No newline at end of file diff --git a/docs/tutorial-extras/_category_.json b/docs/tutorial-extras/_category_.json deleted file mode 100644 index a8ffcc1..0000000 --- a/docs/tutorial-extras/_category_.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "label": "Tutorial - Extras", - "position": 3, - "link": { - "type": "generated-index" - } -} diff --git a/docs/tutorial-extras/img/docsVersionDropdown.png b/docs/tutorial-extras/img/docsVersionDropdown.png deleted file mode 100644 index 97e4164..0000000 Binary files a/docs/tutorial-extras/img/docsVersionDropdown.png and /dev/null differ diff --git a/docs/tutorial-extras/img/localeDropdown.png b/docs/tutorial-extras/img/localeDropdown.png deleted file mode 100644 index e257edc..0000000 Binary files a/docs/tutorial-extras/img/localeDropdown.png and /dev/null differ diff --git a/docs/tutorial-extras/manage-docs-versions.md b/docs/tutorial-extras/manage-docs-versions.md deleted file mode 100644 index ccda0b9..0000000 --- a/docs/tutorial-extras/manage-docs-versions.md +++ /dev/null @@ -1,55 +0,0 @@ ---- -sidebar_position: 1 ---- - -# Manage Docs Versions - -Docusaurus can manage multiple versions of your docs. - -## Create a docs version - -Release a version 1.0 of your project: - -```bash -npm run docusaurus docs:version 1.0 -``` - -The `docs` folder is copied into `versioned_docs/version-1.0` and `versions.json` is created. - -Your docs now have 2 versions: - -- `1.0` at `http://localhost:3000/docs/` for the version 1.0 docs -- `current` at `http://localhost:3000/docs/next/` for the **upcoming, unreleased docs** - -## Add a Version Dropdown - -To navigate seamlessly across versions, add a version dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -export default { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'docsVersionDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The docs version dropdown appears in your navbar: - -![Docs Version Dropdown](./img/docsVersionDropdown.png) - -## Update an existing version - -It is possible to edit versioned docs in their respective folder: - -- `versioned_docs/version-1.0/hello.md` updates `http://localhost:3000/docs/hello` -- `docs/hello.md` updates `http://localhost:3000/docs/next/hello` diff --git a/docs/tutorial-extras/translate-your-site.md b/docs/tutorial-extras/translate-your-site.md deleted file mode 100644 index b5a644a..0000000 --- a/docs/tutorial-extras/translate-your-site.md +++ /dev/null @@ -1,88 +0,0 @@ ---- -sidebar_position: 2 ---- - -# Translate your site - -Let's translate `docs/intro.md` to French. - -## Configure i18n - -Modify `docusaurus.config.js` to add support for the `fr` locale: - -```js title="docusaurus.config.js" -export default { - i18n: { - defaultLocale: 'en', - locales: ['en', 'fr'], - }, -}; -``` - -## Translate a doc - -Copy the `docs/intro.md` file to the `i18n/fr` folder: - -```bash -mkdir -p i18n/fr/docusaurus-plugin-content-docs/current/ - -cp docs/intro.md i18n/fr/docusaurus-plugin-content-docs/current/intro.md -``` - -Translate `i18n/fr/docusaurus-plugin-content-docs/current/intro.md` in French. - -## Start your localized site - -Start your site on the French locale: - -```bash -npm run start -- --locale fr -``` - -Your localized site is accessible at [http://localhost:3000/fr/](http://localhost:3000/fr/) and the `Getting Started` page is translated. - -:::caution - -In development, you can only use one locale at a time. - -::: - -## Add a Locale Dropdown - -To navigate seamlessly across languages, add a locale dropdown. - -Modify the `docusaurus.config.js` file: - -```js title="docusaurus.config.js" -export default { - themeConfig: { - navbar: { - items: [ - // highlight-start - { - type: 'localeDropdown', - }, - // highlight-end - ], - }, - }, -}; -``` - -The locale dropdown now appears in your navbar: - -![Locale Dropdown](./img/localeDropdown.png) - -## Build your localized site - -Build your site for a specific locale: - -```bash -npm run build -- --locale fr -``` - -Or build your site to include all the locales at once: - -```bash -npm run build -```