next-international icon indicating copy to clipboard operation
next-international copied to clipboard

Internationalizing content files (e.g. MDX and contentlayer)

Open zackrw opened this issue 2 years ago • 12 comments

Is your feature request related to a problem? Please describe. i18n for react components is easily supported, but does https://next-international.vercel.app/ recommend a solution for content files, e.g. using contentlayer and mdx.

Describe the solution you'd like When a user goes to /blog or /docs using contentlayer, e.g. https://ui.shadcn.com/docs, it works just as well as other routes.

Describe alternatives you've considered I'm not sure this belongs in next-international or if there needs to be a combination of libraries.

zackrw avatar Nov 15 '23 18:11 zackrw

Great question. Right now, we don't have any example/guide/documentation on this topic, but my take is that if it's markdown, it shouldn't be a translation in-app, and should instead come from an external CMS.

QuiiBz avatar Nov 16 '23 12:11 QuiiBz

Hello @zackrw I'm working on something about this concern.

https://github.com/Tirraa/dashboard_rtm/

It's documented here:

  • https://github.com/Tirraa/dashboard_rtm/tree/main/doc

Notice that it is ultra-beta-version work... I would be very glad to have some feedback/questions about it. :)

gustaveWPM avatar Nov 18 '23 18:11 gustaveWPM

Okay great. I'm happy to be an alpha tester. In terms of the API, being able to use t() or equivalent in .md/.mdx is enough I think. Will that be possible?

For example, if there was a simple <Trans> component, I could compile that in mdx-components.tsx ... but I'm not sure if that would end up "just working" when contentlayer compiles it.

Not sure if you're doing it this way, but I'm curious what the API / DX will look like?

zackrw avatar Nov 18 '23 23:11 zackrw

Huummmm…

No, that's not really what I did. Posts are stored as mdx in folders like:

  • /posts/category/sub-category/language
  • /posts/category/sub-category (for the default language)

Creating an mdx with the same file name in two respective folders is sufficient. For instance:

  • /posts/category-one/subcategory-one/en/post-01.mdx (post-01.mdx, in English)
  • /posts/category-one/subcategory-one/post-01.mdx (post-01.mdx, in the default language... let's assume: "In French").

All the blog posts generated by ContentLayer will have the following computed fields:

  • language,
  • category,
  • subcategory,
  • slug,
  • and url (internationalised).

Automatically created at build time.

I've also started to ensure that there is a "Generic" type so that all posts can be handled without having to worry about their DocumentType or having to handle allDocuments every time, since the code is built so that they all respect the same structure. (It is the PostBase type in my codebase.)

Note: it remains possible to create a folder other than the posts folder, and start adding another configuration and management for this part on your own, using contentDirInclude.


I'm trying to make everything as transparent as possible, so there's no MDX "compilation" apart from ContentLayer. I use the useMDXComponent hook for that. As it is the case in Taxonomy by Shadcn. (See also: My Favorite Way to Use Markdown in NextJS)

In practice, I'm trying to build a codebase that allows you to simply create your MDX files, your categories and sub-categories folders, and have everything mapped almost automatically (here, I say "Almost", because it's still necessary to adjust some tweakers so that the mapping logic evolves while remaining typesafe and in line with ContentLayer's expectations).

For analyzing the consistency between the internationalization configuration (category and sub-category titles, for example), ~~I've written a little "Static Analyzer" that checks whether the content of the internationalization schema is consistent with the filesystem (and likewise for a BlogArchitecture type, which isn't yet automatically generated).~~

EDIT: the static analyzer has been removed, replaced by code generation at prebuild.

Also, this is aiming to be correctly handled by Next-Sitemap, so that all the blog categories, subcategories, and posts pages are all statically generated and included in the sitemap.


EDIT: I refactored a lot of things to make it easier (including automatic code generation), and I'm continuing to work on making it as simple as possible, with the aim of creating a lib.

  • https://github.com/tirraa/dashboard_rtm/
  • https://github.com/Tirraa/dashboard_rtm/doc

gustaveWPM avatar Nov 19 '23 07:11 gustaveWPM

Hi! I may be late. MDX posts don't need to be translated, the usage is to create a folder for each language. And for contentlayer, I created a mapping function inside the config file for all posts, which output a json file (that way posts slug can be translated, and don't need to be the same in each folder) It is what I did in this project : https://github.com/PxlSyl/tailwind-nextjs-starter-blog-i18n/tree/main

PxlSyl avatar Dec 27 '23 10:12 PxlSyl

Hi! I may be late. MDX posts don't need to be translated, the usage is to create a folder for each language. And for contentlayer, I created a mapping function inside the config file for all posts, which output a json file (that way posts slug can be translated, and don't need to be the same in each folder) It is what I did in this project : https://github.com/PxlSyl/tailwind-nextjs-starter-blog-i18n/tree/main

Very interesting one! I may get some inspiration from your repo. Thank you!

gustaveWPM avatar Dec 27 '23 11:12 gustaveWPM

Hi! I may be late. MDX posts don't need to be translated, the usage is to create a folder for each language. And for contentlayer, I created a mapping function inside the config file for all posts, which output a json file (that way posts slug can be translated, and don't need to be the same in each folder) It is what I did in this project : https://github.com/PxlSyl/tailwind-nextjs-starter-blog-i18n/tree/main

Very interesting one! I may get some inspiration from your repo. Thank you!

No pb! Only thing I'm struggling with this repo rn, is to find the right way to have valid dynamic robot.ts and sitemap.ts files, such a pain lol! Also working on another free template (not yet available)

PxlSyl avatar Dec 27 '23 21:12 PxlSyl

Hello! Just to say that I think I'm making pretty good progress on the PoC I'm building. I think I'll be able to present it to you and talk about it a bit more in the next two or three weeks.

gustaveWPM avatar Jan 25 '24 03:01 gustaveWPM

Hello!

I think I've got a PoC that could do the job as a glue between Next International and Contentlayer.

It's available here:

  • https://github.com/Tirraa/dashboard_rtm

And documented here (you can skip the navbar and sidebar folders):

  • https://github.com/Tirraa/dashboard_rtm/tree/main/doc

It's also pretty much tested correctly (I guess):

  • https://github.com/Tirraa/dashboard_rtm/actions/runs/7854133757

Btw: maybe I'll come back to you with some videos to present my approach. Perhaps it will be a little more "Accessible" with "Videmos" (lol).

I'd love to know if, by skimming the documentation, this approach might appeal. There would still need to be a further level of abstraction to consider making it a library as a Next International "Plugin".

I think it could be done (and I'd love to!).

gustaveWPM avatar Feb 10 '24 10:02 gustaveWPM

Hello!

https://www.youtube.com/watch?v=glfaad1h4GM&list=PLXzntcv-DhAqSJ1y8o_SH6tpfDkW6-X71

I've made some videos to present the tip of the iceberg of my project. The purpose is not to be exhaustive, but to give a quick overview.

ping @QuiiBz I'd be curious to know what you think about this.

gustaveWPM avatar Feb 17 '24 16:02 gustaveWPM

Thanks for sharing this! I'll be traveling next week but will try to check it out as soon as possible.

QuiiBz avatar Feb 17 '24 17:02 QuiiBz

Thanks for sharing this! I'll be traveling next week but will try to check it out as soon as possible.

There's no hurry! Have fun.

gustaveWPM avatar Feb 17 '24 17:02 gustaveWPM