# ☁️ BROJS.RU Landing - Полная документация
## 📋 Оглавление
1. [Обзор проекта](#обзор-проекта)
2. [Структура проекта](#структура-проекта)
3. [Static Site Generation (SSG)](#static-site-generation-ssg)
4. [Страница пользовательского соглашения](#страница-пользовательского-соглашения)
5. [Команды и скрипты](#команды-и-скрипты)
6. [Технологии](#технологии)
7. [Deployment](#deployment)
---
## Обзор проекта
**BROJS.RU Landing** - это статический лендинг платформы обучения фронтенд-разработке на базе React + SSG.
### Особенности:
✅ **React 18** с TypeScript
✅ **Static Site Generation** - HTML вкомпилирован для SEO
✅ **Chakra UI** - современный UI framework
✅ **i18next** - мультиязычность (ru/en)
✅ **React Router** - клиентский роутинг
✅ **Hydration** - гидратация статического контента
### Страницы:
- **`/`** - главная страница "в разработке"
- **`/terms`** - пользовательское соглашение (полное, SEO-оптимизировано)
---
## Структура проекта
```
bro.landing/
├── src/
│ ├── pages/
│ │ ├── under-construction/ # Главная страница
│ │ ├── terms/ # Пользовательское соглашение
│ │ └── index.ts # Экспорт страниц
│ ├── app.tsx # Root компонент
│ ├── dashboard.tsx # Роутинг
│ ├── index.tsx # Entry point + hydration
│ └── index.ejs # HTML шаблон
├── scripts/
│ ├── prerender-multi.js # ⭐ Основной SSG скрипт
│ └── ssr-prerender.js # Альтернативный SSR
├── dist/ # Сборка (генерируется)
│ ├── index.html # Главная (SSG)
│ ├── terms.html # Соглашение (SSG)
│ └── index.js # React bundle
├── package.json
└── cloud.md # 📚 Эта документация
```
---
## Static Site Generation (SSG)
### Как работает?
1. **Webpack** собирает React → `dist/index.js`
2. **Скрипт `prerender-multi.js`** автоматически:
- Читает `dist/index.html` (пустой шаблон)
- Вставляет статический контент в `
`
- Генерирует `dist/terms.html` из `terma.md`
3. **React hydration** при загрузке оживляет статический HTML
### Преимущества SSG:
- 🚀 **Быстрая загрузка** - контент виден до загрузки JS
- 🔍 **SEO** - поисковики индексируют полный HTML
- ♿ **Доступность** - работает без JavaScript
- 📊 **Метрики** - улучшенные FCP и LCP
### Hydration в index.tsx:
```typescript
const hasPrerenderedContent = MOUNT_NODE.hasChildNodes();
if (hasPrerenderedContent) {
hydrateRoot(MOUNT_NODE, ); // Оживляем статику
} else {
createRoot(MOUNT_NODE).render(); // Обычный рендер
}
```
### Скрипт prerender-multi.js:
**Что делает**:
1. Читает `terma.md` (исходник соглашения)
2. Парсит markdown → HTML со стилями
3. Создает `dist/index.html` с контентом главной
4. Создает `dist/terms.html` с полным соглашением (~13KB)
**Автоматический запуск**:
- `npm run build:prod` - после webpack сборки
- `npm run build:prod:ssr` - альтернативный SSR
---
## Страница пользовательского соглашения
### Источник: `terma.md`
⚠️ **Важно**: `terma.md` - единственный источник правды для соглашения!
Чтобы обновить соглашение:
1. Отредактируйте `terma.md`
2. Запустите `npm run build:prod`
3. `dist/terms.html` обновится автоматически
### Структура terma.md:
```markdown
Пользовательское соглашение для BROJS.RU
Последнее обновление: 25 мая 2025 г.
1. Термины
...
10. Контакты
Для обращений: primakov.pro@yandex.ru
```
### React компонент: Terms.tsx
- **Путь**: `src/pages/terms/Terms.tsx`
- **Дизайн**: Chakra UI, официальный стиль документа
- **SEO**: Helmet с meta-тегами
- **Роут**: `/terms` в dashboard.tsx
### SEO-версия: terms.html
Генерируется автоматически из `terma.md`:
```html
Пользовательское соглашение - BROJS.RU
Пользовательское соглашение для BROJS.RU
1. Термины
- Платформа — сайт https://brojs.ru ...
...
```
**Размер**: ~13.6 KB (полный текст + стили)
**Содержание**: Все 10 разделов с подразделами
**Ссылки**: Рабочие теги на email и сайты
### Важные детали:
✅ **Название сайта**: BROJS.RU (не BRO-JS.RU)
✅ **Авторизация**: Yandex + Email (Google и VK исключены)
✅ **Email**: primakov.pro@yandex.ru
---
## Команды и скрипты
### NPM Scripts:
```json
{
"start": "brojs server --port=8099 --with-open-browser",
"build": "npm run clean && brojs build --dev",
"build:prod": "npm run clean && brojs build && node scripts/prerender-multi.js",
"build:prod:ssr": "npm run clean && brojs build && node scripts/ssr-prerender.js",
"clean": "rimraf dist",
"eslint": "npx eslint src",
"prettier": "prettier --write .",
"test": "jest --coverage"
}
```
### Использование:
#### 🔧 Разработка:
```bash
npm start
# → Запускает dev сервер на http://localhost:8099/
# → Hot reload включен
# → Без SSG (быстро)
```
#### 🏗️ Dev сборка:
```bash
npm run build
# → Webpack в dev режиме
# → Без минификации
# → Без SSG
# → Результат: dist/index.html (пустой шаблон)
```
#### 🚀 Production сборка (с SSG):
```bash
npm run build:prod
# → Webpack в production режиме
# → Минификация
# → Автоматический SSG (prerender-multi.js)
# → Результат:
# - dist/index.html (со статическим контентом)
# - dist/terms.html (полное соглашение для SEO)
```
Вывод:
```
✅ Сборка успешно завершена!
🚀 Начинаем мульти-страничный пре-рендеринг...
✅ index.html обновлен
📝 Генерируем полный HTML из terma.md...
✅ terms.html создан с полным контентом
🎉 Пре-рендеринг завершен успешно!
```
#### 🔄 Production сборка (альтернативный SSR):
```bash
npm run build:prod:ssr
# → Использует ssr-prerender.js
# → SSR с jsdom окружением
# → Результат аналогичен build:prod
```
### Другие команды:
```bash
npm run clean # Удалить dist/
npm run eslint # Проверить код
npm run prettier # Форматировать код
npm run test # Запустить тесты
```
---
## Технологии
### Frontend:
- **React 18.3** - UI библиотека
- **TypeScript** - типизация
- **Chakra UI 2.8** - компоненты и стили
- **Emotion** - CSS-in-JS
- **React Router 6** - роутинг
- **React Helmet** - управление
### State & i18n:
- **Redux Toolkit** - state management
- **i18next** - интернационализация
- **i18next-browser-languagedetector** - автоопределение языка
### Build & Dev:
- **@brojs/cli 1.9.5** - сборщик (обертка над webpack)
- **Webpack 5** - бандлер
- **Babel** - транспиляция
- **jsdom** - SSR окружение
### Дополнительно:
- **Lottie React** - анимации
- **Day.js** - работа с датами
- **ESLint** - линтинг
- **Prettier** - форматирование
- **Jest** - тестирование
---
## Deployment
### Docker + Nginx:
Проект разворачивается через Docker контейнер с Nginx.
**Скрипты**:
- `d-scripts/up-nginx.sh` - запуск контейнера
- `d-scripts/stop.sh` - остановка
- `d-scripts/re-run.sh` - перезапуск
**Процесс**:
```bash
# 1. Сборка
npm run build:prod
# 2. Deploy
npm run redeploy
# → Устанавливает зависимости
# → Собирает проект
# → Перезапускает Docker контейнер
```
### Конфигурация Nginx:
Nginx раздает папку `dist/`:
```
https://brojs.ru/ → dist/index.html
https://brojs.ru/terms → React Router → terms.html (fallback)
https://brojs.ru/terms.html → dist/terms.html (прямой доступ)
https://brojs.ru/index.js → dist/index.js
```
### Важно для SEO:
1. **index.html** содержит статический контент (SSG)
2. **terms.html** содержит полное соглашение (SSG)
3. **React Router** работает на клиенте для SPA навигации
4. **Fallback** на статические .html файлы для ботов
---
## 🎯 Чеклист при обновлениях
### Обновление пользовательского соглашения:
- [ ] Отредактировать `terma.md`
- [ ] Проверить что нет Google/VK (только Yandex + Email)
- [ ] Проверить что название сайта: **BROJS.RU**
- [ ] Запустить `npm run build:prod`
- [ ] Проверить `dist/terms.html` (должен быть ~13KB)
- [ ] Задеплоить: `npm run redeploy`
### Добавление новой страницы:
- [ ] Создать компонент в `src/pages/`
- [ ] Экспортировать в `src/pages/index.ts`
- [ ] Добавить роут в `src/dashboard.tsx`
- [ ] Если нужен SSG - обновить `scripts/prerender-multi.js`
- [ ] Собрать и проверить
### Перед деплоем:
- [ ] `npm run eslint` - проверить код
- [ ] `npm run prettier` - форматировать
- [ ] `npm run test` - запустить тесты
- [ ] `npm run build:prod` - собрать
- [ ] Проверить `dist/index.html` и `dist/terms.html`
- [ ] `npm run redeploy` - задеплоить
---
## 🐛 Troubleshooting
### Проблема: terms.html пустой или куцый
**Решение**: Проверьте `terma.md` - это единственный источник контента.
```bash
npm run build:prod
# Проверьте вывод:
# ✅ terms.html создан с полным контентом
```
### Проблема: Hydration warning
**Причина**: Несоответствие серверного и клиентского HTML.
**Решение**: Проверьте что контент в `prerender-multi.js` совпадает с React компонентом.
### Проблема: 404 на /terms
**Nginx**: Убедитесь что настроен fallback на index.html:
```nginx
try_files $uri $uri/ /index.html;
```
### Проблема: SSG не запускается
**Проверьте**:
1. `scripts/prerender-multi.js` существует
2. В `package.json` правильная команда: `build:prod`
3. Нет ошибок в webpack сборке
---
## 📚 Полезные ссылки
- **Сайт**: https://brojs.ru
- **Email**: primakov.pro@yandex.ru
- **Keycloak**: PostgreSQL (auth)
- **Gravatar**: https://gravatar.com
---
## 📝 История изменений
### v2.0.2 (2025-10-24)
- ✨ Добавлена страница `/terms` с пользовательским соглашением
- 🎨 Официальный дизайн юридического документа
- 📄 Автоматическая генерация `terms.html` из `terma.md`
- 🔍 SEO-оптимизация (13.6KB полного контента)
- 🔄 Название сайта: BRO-JS.RU → **BROJS.RU**
- 🔐 Авторизация: только Yandex + Email
- 🧹 Очистка скриптов (удален postbuild, лишние файлы)
### v2.0.1 (2025-10-24)
- 🚀 Static Site Generation (SSG)
- 💡 React 18 hydration
- 📚 Документация по SSG
---
**Вопросы?** → primakov.pro@yandex.ru
**Документация актуальна**: 2025-10-24