Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/markmelior/simple-app

Small and modern pet-projects
https://github.com/markmelior/simple-app

frontend fsd i18n mdx nextjs14 pet-projects seo typescript

Last synced: 2 months ago
JSON representation

Small and modern pet-projects

Awesome Lists containing this project

README

        

## Реализованный функционал

### Интернационализация (i18n)

> Реализован i18n без использования сторонних библиотек

#### Файлы:

- [middleware.ts](/middleware.ts) - основной функционал работы i18n
- [getLang()](src/shared/config/i18n/get-lang.ts) - возвращает выбранный язык `en | ru`
- [useLang()](src/shared/config/i18n/use-lang.ts) - как `getLang()`, только для клиентского компонента
- [getDictionary()](src/shared/config/i18n/dictionaries.ts) - возвращает объект с переводами `ключ-значение`
- [useDictionary()](src/shared/config/i18n/use-dictionary.ts) - как `getDictionary()`, только для клиентского компонента
- [type Dictionary](src/shared/config/i18n/dictionaries.ts)
- [/dictionary](src/shared/config/i18n/dictionaries/) - директория с json файлами переводов
- [Link](src/shared/config/i18n/link.tsx) - компонент Link для i18n

#### Особенности:

Все компоненты `Link` экспортируем из `@/shared/config/i18n` !

Не нужно прокидывать props в каждый компонент, где используется перевод:

```diff
- export const Navbar = ({ dict }: { dict: Dictionary['ui'] }) => {...}

+ export const Navbar = async () => {
+ const dictionary = await getDictionary();
```

Не нужно передавать язык в `getDictionary(lang)`, как это реализовано в [документации Next.js](https://nextjs.org/docs/app/building-your-application/routing/internationalization#localization):

```diff
- getDictionary(lang)
+ getDictionary()
```

Просто используем в любом серверном компоненте `const dict = await getDictionary();`, прокидываем в клиентский компонент как props `{ dict }: { dict: Dictionary['ui'] }` или используем `useDictionary()`

---

## MDX

> MDX синхронизирован с i18n

#### Реализация MDX:

- [`app/[lang]/projects/[category]/[name]/page.tsx`](/app/[lang]/projects//[category]/[name]/page.tsx) - layout для mdx файлов проектов;
- [`app/[lang]/projects/[category]/page.tsx`](/app/[lang]/projects/[category]/page.tsx) - страница отображения проектов из категории;
- [getMdx()](/src/shared/config/mdx/get-mdx.ts) - получение metadata и контента из mdx;
- [getProject(category, name)](/src/entity/project/model/services/get-project.ts) - получение проекта по категории и имени;
- [getProjectsByCategory(category)](/src/entity/project/model/services/get-projects-by-category.ts) - получение всех проектов в выбранной категории;
- [getProjects()](/src/entity/project/model/services/get-projects.ts) - получение всех категорий и проектов;
- [mdx-components.tsx](/src/shared/config/mdx/mdx-components.tsx) - настройка отображения mdx;
- [MDXRemote](/src/shared/config/mdx/mdx-remote.tsx) - общая настройка MDXRemote;
- [rehypeExtractCodeProps](/src/shared/config/mdx/plugins/rehype-extract-code-props.ts) - самописный rehype-плагин для чтения пар ключ-значение в коде.

Вывод mdx страниц и метаданных происходит за счёт преобразования его через [gray-matter](https://www.npmjs.com/package/gray-matter). Рендер mdx через MDXRemote `next-mdx-remote/rsc` для серверного рендеринга (смотреть [MDXRemote](/src/shared/config/mdx/mdx-remote.tsx))

---

## Архитектура проекта

Проект написан в соответствии с архитектурной методологией [Feature-Sliced Design](https://feature-sliced.design/docs/get-started/tutorial) и [AppRouter](https://nextjs.org/docs/app) (Next.js).

- [shared](/src/shared/) - функциональность многократного использования;
- [entity](/src/entity/) - бизнес сущности;
- [features](/src/features/) - повторно используемые реализации целых функций продукта;
- [widgets](/src/widgets/) - большие автономные блоки функциональности или пользовательского интерфейса;
- [app](/src/app/) - все, что обеспечивает работу приложения.