Blog is now bilingual

Blog is now bilingual

Daily short news for you
  • After waking up, I saw the news feed flooded with articles about Microsoft rewriting the TypeScript compiler - tsc in Go, achieving performance that is 10 times faster than the current one. Wow!

    But when I saw this news, the question immediately popped into my head: "Why not Rust?" You know, the trend of rewriting everything in Rust is hotter than ever, and it’s not an exaggeration to say that it's sweeping through the rankings of previous legacy tools.

    What’s even more interesting is the choice of Go - which supposedly provides the best performance to date - as they say. Many people expressed disappointment about why it wasn’t C# instead 😆. When something is too famous, everything is scrutinized down to the smallest detail, and not everyone listens to what is said 🥶

    Why Go? #411

    » Read more
  • I read this article Migrating Off Oh-My-Zsh and other recent Yak Shavings - the author essentially states that he has been using Oh-My-Zsh (OMZ) for a long time, but now the game has changed, and there are many more powerful tools that have come out, so he realizes, oh, he doesn't need OMZ as much anymore.

    I also tried to follow along because I find this situation quite similar to the current state. It was surprising to discover something new. I hope to soon write a post about this next migration for my readers 😁

    » Read more
  • Maybe I need to plan to rewrite some of the blog's signature posts. There are articles that are very detailed but no one reads. On the other hand, there are posts from a few years ago, back when I was just starting to write, that many people read 🥲

    » Read more

The problem

A while ago, I consulted with the CTO about whether I should advertise the blog to make it more well-known. He hesitated for a moment and replied, "I don't think so. If possible, try expanding your user base to other countries." Before that, I thought I could spend money on advertising on some social media platforms to promote my blog to more people, thereby increasing traffic and prioritize displaying the website in search results. But after that answer, I suddenly remembered the plan I had before writing: "The blog must be in English."

But you know, I'm not good at English. I can understand some documents, but when it comes to speaking or writing... I had to postpone my plan and hope that someday someone would translate the articles for me - I thought. And then suddenly, one day, ChatGPT appeared, the most advanced natural language model. To put it simply, it can understand and write responses like a human, not just simple sentences assembled by a robot. If I ask it to translate my articles, the English writing style is likely to become smoother compared to using traditional tools like Google Translate.

Actually, I wanted to integrate the ChatGPT API into the admin page to have it directly translate Vietnamese articles into English. But I have been waiting for it to open the API in Vietnam for a long time. Unable to wait any longer, last week was a busy week as I just finished implementing the multilingual blog feature. Yes, I just integrated i18n for it.

The process

This is not the first time I have built a multilingual website. Before that, I participated in some projects, either building from scratch or contributing to maintenance and adding new features.

2coffee.dev was created quite a while ago and did not initially integrate i18n, so it took some time to research some i18n-supporting modules.

It was not difficult to find, @nuxtjs/i18n is a popular module for Nuxt.js, so there is no reason not to use it. Take a look at the documentation to see how to install, configure, and what it can do.

After researching, I started testing some cases to see how it works and if it meets my requirements. For example, how to switch languages, whether to support language switching by path (e.g., /vi for Vietnamese, /en for English, and / as the default for Vietnamese), how to configure different article URLs between the two languages (e.g., the current article URL is /bai-viet/ten-bai-viet but I want it to be /articles/article-title in English), and how to configure links on the website to point to the correct URL based on the language... there are many things to do.

And finally, the most important thing is the SEO configuration for a multilingual website. You have to do something to let search engines know that your website has more than one language, as well as the Vietnamese and English content of the same article to optimize search results. Luckily, before that, I had read about this issue, and Google also has a very detailed article on how to declare a multilingual website in Overview of international and multilingual site topics. Depending on the case, for example, I am declaring the sitemap address with Google Search Console so they can quickly update the information, but previously the sitemap was configured with only one language, so I need to add multilingual support.

Last week, I quickly implemented it. You see, the series of articles about Rust was temporarily paused to focus on completing the multilingual feature.

Challenges

Things never go as smooth as we want, and the integration of multilingual support is no exception. In fact, I almost had to give up because of an inexplicable bug at the last minute.

Since I did not integrate i18n from the beginning, I had to go back and find all the places where the language was displayed in the code, put them into language configuration files, translate them, and replace them with i18n module language display support.

The most time-consuming part was integrating paths in the <nuxt-link> tag, specifically the to prop. Normally, we use <nuxt-link to="/path"> to create links to the /path router. But as I mentioned, the article URLs between Vietnamese and English are different, so I had to use a new syntax: <nuxt-link :to="localePath({ name: 'bai-viet-id', params: { id: article.url } })">. The structure in localePath includes name as the route name and params to declare params in the URL for the new link. To make it easier to understand, take a look at my current folder structure:

Folder structure

Oh, then the name should just be bai-viet, why bai-viet-id? Yes, it took me quite some time to figure out how to declare a router that contains params, specifically _id here.

At this point, everything was almost done, and then I ran npm run generate to create the static website, but many errors appeared, and my efforts were to "fix" them. If I used SSR, many issues would be simpler, but I chose SSG to increase page loading speed, and SSG has a different way of building code compared to SSR, so I had to modify the code to be compatible with it.

Finally, when I thought everything was ready for deployment, upon checking again, I found that on the first load, my website had a brief layout glitch, even though it was just a small flicker, it was noticeable and annoying. Not to mention that this also caused search engines to rate it poorly in terms of performance.

If other errors leave clear notifications about the cause and location, with a layout issue, that's too far-fetched. I'm sure many people have been in this situation and desperate in trying to guess where the problem lies. As for me, I checked out each commit to see where the issue started. Quora, it appeared after the commit that added the i18n configuration.

Strange! What does i18n have to do with the layout? I thought the same, and I spent a lot of time searching for answers online, but it seems like no one has encountered this issue. I guess I need to create an issue about this problem on Github? Hmm... it would probably take a lot of time, not to mention I need to explain the project structure along with the issues I am facing to wait for someone else to answer. =='

I had to take matters into my own hands, so I debugged the differences between the two commits before and after adding the i18n module and discovered something. In the commit after adding the module, there was a CSS file that was loading slower, and it was also the CSS file for the broken component. Continuing to investigate why it was loading slower, I found that it was executed after a JavaScript file was downloaded, in other words, that JavaScript file contained code to download the CSS. So, that means the i18n module is trying to change the project structure it builds!?

I looked into the build configuration in the nuxt.config.js file, and there was an option enabled:

build: {
    …
    extractCSS: {
      ignoreOrder: true,  
    },  
}

This is an option to split CSS files into smaller files to increase loading speed. Perhaps the splitting of CSS conflicted with i18n, causing it to consider the other CSS file unimportant and can be loaded later, resulting in a brief layout glitch. I turned off that option, and... everything started working again. Luckily!

Next steps

The first step is writing code, and then it is a long journey.

First, I will ask ChatGPT to translate some articles that I feel it can handle into English, make some adjustments like formatting, images... because when I tried to translate an article, it didn't return the markdown format for me to copy. Some articles have code formatted in backticks (`), and they were broken when displayed in ChatGPT... so, after translation, many things still need to be edited before publishing a complete article.

Evaluate the effectiveness of SEO as well as fixing any future issues or problems that arise, because I don't have much experience in managing multilingual websites.

Although it's a translation, I will try to read through the translated articles and hope to learn more through this process!

Premium
Hello

The secret stack of Blog

As a developer, are you curious about the technology secrets or the technical debts of this blog? All secrets will be revealed in the article below. What are you waiting for, click now!

As a developer, are you curious about the technology secrets or the technical debts of this blog? All secrets will be revealed in the article below. What are you waiting for, click now!

View all

Subscribe to receive new article notifications

or
* The summary newsletter is sent every 1-2 weeks, cancel anytime.

Comments (1)

Leave a comment...
Avatar
Ẩn danh7 months ago
chào bạn có thể hướng dẫn rõ hơn về cách cài đặt đa ngôn ngữ cho blog không ạ?
Reply