Solving i18n for React Server Components

Rate this content
Bookmark

How the transition to React Server Components enables better internationalization solutions.

This talk has been presented at React Summit 2024, check out the latest edition of this React Conference.

FAQ

Before server components, translations were loaded one page at a time using namespaces, which required bookkeeping to manage which messages were needed for each page.

The proposed solution is to use a giant JavaScript file with all messages exported separately, allowing import statements to manage dependencies and enabling tools like Webpack or TurboPack to tree-shake and minimize the loaded messages.

Paraglide.js is a tool developed by Loris that generates a giant messages file from translation files, allowing developers to use import statements to manage translations without imperative loading.

Developers should stop using namespaces because they are no longer fit for purpose with server components, requiring too much effort and overhead to manage fine-grained loading.

Namespaces are inefficient with server components because the unit of message loading changes, requiring fine-grained loading for client components and making imperative loading cumbersome and high-overhead.

The new approach benefits client components by enabling fine-grained loading, ensuring only the necessary messages are sent to the client, reducing bandwidth usage.

Import statements express the relationship between components and messages, allowing build tools to analyze and tree-shake unused messages, optimizing the loading process.

The goal is to build a multilingual app while sending as few bytes as possible over the wire, being fine-grained in loading messages and translations to respect users' bandwidth.

Loris builds internationalization tooling at a company called Inlang.

The main focus is on internationalization for server components, specifically string translations, layouts, and components, not content.

Loris Sigrist
Loris Sigrist
7 min
18 Jun, 2024

Comments

Sign in or register to post your comment.
Video Summary and Transcription
The Talk discusses internationalization for server components and the challenge of loading translations efficiently. It suggests using import statements in JavaScript to optimize message loading and eliminate the need for namespaces. Tree shaking and tools like Paraglide.js can help minimize message delivery and simplify the process. Overall, the Talk emphasizes the importance of efficient internationalization practices in building multilingual apps.

1. Introduction to Internationalization

Short description:

I'm Loris from Inlang, and today I'll talk about internationalization for server components. Our goal is to build a multilingual app while minimizing data sent over the wire. We used to load translations per page into namespaces, but this becomes challenging with server components. On the server, you can load everything, but on the client, it's inefficient to load a namespace for each component.

Hi, I'm Loris. I build internationalization tooling at a company called Inlang, and today I'm going to be talking about internationalization for server components.

So, just that we're all on the same page, I'm going to be talking about string translations, your layouts, your components, not your content. So, when we're doing internationalization, our goal is, of course, to build a multilingual app while sending as few bytes as possible over the wire. We want to be really fine-grained in what we reach messages and translations we load so that we only display what is actually necessary. We respect our users' bandwidth.

Before server components, the unit in which we would load translations is one page at a time. So, it would have a certain set of messages that you would need on one page, certain set of messages that you would need on another page. So, what you would do is you would sort them into namespaces, names groups. Then you would imperatively load these namespaces with some sort of load namespace functions. Each item in a library is going to have some sort of equivalent to that one.

Now, what you would usually end up with is kind of one namespace per page. Then if you have a shared component per page, maybe an auth bar or a component that's used in many pages, you would create a second namespace just for that. It also imperatively loads that one when you load the page. So, you kind of need to keep track of, okay, which messages do I need exactly and which ones do I not need. You also often have some sort of common namespace where you have messages that are used in many different places, generic stuff, forwards, backwards. So, what you can see here is that you do end up with quite a few namespaces usually per page. I'm sure that if you've built a lot of multilingual apps, you're going to be familiar with this.

But there's quite a bit of bookkeeping, but usually it's staged manageable. You end up with between two and five namespaces per page. It's a bit of work, but it's doable. But this pattern works is a lot more difficult to pull off well if you introduce server components into the mix, because the unit in which you load messages is no longer per page. Now you're trying to load exactly the messages that are needed for the client components that you're going to render. With server components, your page is kind of this patchwork of stuff that's rendered on the server and stuff that's on the client, and you need messages in both, you need translations in both. But the requirements on how you actually load these messages is very, very different. On the server, you really don't need to do any fine-grained loading at all. You can just load everything, be gluttonous, and just use what you want, like you like it. Do no bookkeeping at all. That's wonderful. But if we were to stick with the whole namespace and imperative loading approach, on the client, it's going to be very, very painful, because you're going to end up creating a namespace for each client component, then you need to imperative load that one with the page, and it's going to be a lot of work, a lot of overhead.

2. Efficient Loading with Import Statements

Short description:

We want to load only the necessary messages for a page and client components. Namespaces are no longer suitable for server components. Instead, we can use import statements in JavaScript to express dependencies and optimize message loading. By having all messages in one JavaScript file, build tools can analyze and remove unused messages. Tree shaking ensures minimal message delivery. Tools like Paraglide.js can generate the necessary files, eliminating the need for imperative loading. Stop using namespaces and try Paraglide.js.

We really only want to load the messages that are used on a page and used in client components on that page. So kind of these competing scenarios where on the one hand, we really need really, really, really fine-grained loading, and on the server, we don't need fine-grained loading at all. But of course, we can't really do separate APIs for the server and the client, because when we develop our apps, our apps are living documents. Client components become server components, become client components, add components, remove components. So keeping the imperative loading in sync with all of that is going to be way too much work, way too much overhead.

So when it comes to loading translations, namespaces really are no longer the way to go when you introduce server components into the mix, because it just becomes a prohibitive amount of effort that you need to put in to actually load what you need and only what you need. Surely there has to be a better way. Let's take a step back and start thinking about what we're actually trying to do when we do these namespace releases. What we're trying to express is that this component depends on these messages, this code depends on that. And in JavaScript, we have this wonderful tool called an import statement, which expresses that relationship very, very well. And we have tools that can analyze that, at bundlers that can tweak and everything that can really, really take advantage of that.

Let's imagine that instead of sorted namespaces or JSON files, we had kind of one giant JavaScript file where all of our messages that exist in our app are present and exported separately. Now let's not worry where we got that file from. Let's just assume we have it. You can see this on the left here, what we can do in our components, regardless of if they're client components or server components, we can just import from that file and use the messages that we want. And our build tools, or Redpack or TurboPack, is going to be smart enough to see, okay, we're using exactly this message and it's only these messages and we're using them on the client. It's able to do this separately for the server and the client, even though the code is identical. So it's going to be able to see which messages we are using, and it's going to be able to remove all the rest. So we kind of get the minimum set of messages that is used on the client. If you're developing, it's very common for your client component to become a server component or vice versa, usually just by adding or removing the use client bit there. And the tree shaking in our bundlers is clever enough to do this properly. So if I remove the use client there, all the messages would no longer be sent to the client. We're sending as few bytes as possible. This is perfect, fine-grained loading.

Now, of course, you probably don't want to actually write such a messages file yourself. It's pretty straightforward if you're just using strings, but if you have your ICU message formats strings, there's a bunch of plurals, currency formats and all that. It's going to be very, very tedious to maintain. And of course, your translators are not going to be able to work with it. So you're going to want to generate this file somehow. There are a bunch of tools available in order to do this. But I myself, I have been working on one. It's called a Paraglide.js. It does exactly what I just said, just takes an oil translation files, gives you a giant messages file, and then you can just use that use input statements to express all your relationships that you need. And you no longer need to worry about doing any imperative loading at all. That's my elevator pitch. Please stop using namespaces for loading stuff. They're not fit for purpose anymore. And try a library like Paraglide.js. Thank you.

Check out more articles and videos

We constantly think of articles and videos that might spark Git people interest / skill us up or help building a stellar career

Simplifying Server Components
React Advanced 2023React Advanced 2023
27 min
Simplifying Server Components
Top Content
Watch video: Simplifying Server Components
React server components simplify server-side rendering and provide a mental model of components as pure functions. Using React as a library for server components allows for building a basic RSC server and connecting it to an SSR server. RSC responses are serialized virtual DOM that offload code from the client and handle interactivity. The client manifest maps serialized placeholders to real components on the client, enabling dynamic rendering. Server components combine the best of classic web development and progressive enhancement, offering the advantage of moving logic from the client to the server.
Exploring React Server Component Fundamentals
React Day Berlin 2023React Day Berlin 2023
21 min
Exploring React Server Component Fundamentals
Top Content
Watch video: Exploring React Server Component Fundamentals
This Talk introduces React Server Components (RSC) and explores their serialization process. It compares RSC to traditional server-side rendering (SSR) and explains how RSC handles promises and integrates client components. The Talk also discusses the RSC manifest and deserialization process. The speaker then introduces the Waku framework, which supports bundling, server, routing, and SSR. The future plans for Waku include integration with client state management libraries.
And Now You Understand React Server Components
React Summit 2024React Summit 2024
27 min
And Now You Understand React Server Components
Top Content
In this Talk, Kent C. Dodds introduces React Server Components (RSCs) and demonstrates how to build them from scratch. He explains the process of integrating RSCs with the UI, switching to RSC and streaming for improved performance, and the benefits of using RSCs with async components. Dodds also discusses enhancements with streaming and server context, client support and loaders, server component rendering and module resolution, handling UI updates and rendering, handling back buttons and caching, and concludes with further resources for diving deeper into the topic.
A Practical Guide for Migrating to Server Components
React Advanced 2023React Advanced 2023
28 min
A Practical Guide for Migrating to Server Components
Top Content
Watch video: A Practical Guide for Migrating to Server Components
React query version five is live and we'll be discussing the migration process to server components using Next.js and React Query. The process involves planning, preparing, and setting up server components, migrating pages, adding layouts, and moving components to the server. We'll also explore the benefits of server components such as reducing JavaScript shipping, enabling powerful caching, and leveraging the features of the app router. Additionally, we'll cover topics like handling authentication, rendering in server components, and the impact on server load and costs.
Server Components: The Epic Tale of Rendering UX
React Summit 2023React Summit 2023
26 min
Server Components: The Epic Tale of Rendering UX
Top Content
Watch video: Server Components: The Epic Tale of Rendering UX
This Talk introduces server components in React, which provide an intermediate format for rendering and offer advantages for both client-side and server-side rendering. Server components reduce bundle size on the client and improve search engine optimization. They abstract the rendering process, allowing for faster rendering and flexibility in choosing where to render components. While server components are still in the experimental stage, Next.js is a good starting point to try them out.
RSCs In Production: 1 Year Later
React Summit 2024React Summit 2024
24 min
RSCs In Production: 1 Year Later
This Talk explores the experience of shipping server components in production and highlights the benefits and challenges of using Server Components in Next.js apps. The Talk discusses the deployment of UploadThing and the use of AppRouter for safe production usage. It delves into the implementation of different layouts, data fetching, and code centralization for improved performance. The Talk also covers the use of server components for performance optimization and latency handling. Additionally, it explores the use of Edge and Lambda for partial pre-rendering and the challenges faced with webpack performance and hydration. Overall, the Talk emphasizes the benefits and challenges of working with Server Components in Next.js applications.

Workshops on related topic

Next.js 13: Data Fetching Strategies
React Day Berlin 2022React Day Berlin 2022
53 min
Next.js 13: Data Fetching Strategies
Top Content
WorkshopFree
Alice De Mauro
Alice De Mauro
- Introduction- Prerequisites for the workshop- Fetching strategies: fundamentals- Fetching strategies – hands-on: fetch API, cache (static VS dynamic), revalidate, suspense (parallel data fetching)- Test your build and serve it on Vercel- Future: Server components VS Client components- Workshop easter egg (unrelated to the topic, calling out accessibility)- Wrapping up
The Gateway to Backend: A Frontend Developer's Guide to Full-Stack Development
React Summit US 2023React Summit US 2023
160 min
The Gateway to Backend: A Frontend Developer's Guide to Full-Stack Development
Top Content
WorkshopFree
Amy Dutton
Amy Dutton
This workshop will guide you through the product development life cycle of creating a real-world web application. You will learn about React Server Components, building a design system within Storybook, and using frontend development to approach becoming a full-stack developer. The workshop will cover increasing confidence in your application with unit tests and implementing authentication and authorization. You'll have the opportunity to work through product features and examine a real-world RedwoodJS project, gaining valuable experience in real-world product development. RedwoodJS makes it simple to approach full-stack development, and this workshop will give you the skills you need to create your own real-world web applications.
Advanced Application Deployment Patterns with React Server Components (feat. a DIY RSC Framework)
React Summit US 2023React Summit US 2023
104 min
Advanced Application Deployment Patterns with React Server Components (feat. a DIY RSC Framework)
Top Content
WorkshopFree
 Greg Brimble
Greg Brimble
The developer ecosystem is always moving fast and this year has proved no exception. React Server Components can offer a significant improvement to developer experience and to application performance. But I think it's fair to say that this new server-first paradigm can be tricky to wrap your head around!In the first half of this workshop, we'll explore React Server Components from the ground-up: building our own mini meta-framework to help us understand how RSCs work. We'll discover exactly what is produced by an RSC build and we'll connect those pieces together to form a full application.Next, we'll deploy it! Cloudflare have also had a busy year too — Smart Placement, in particular, is a new technology that we've developed which fits the RSC model perfectly. We'll explore why that makes sense for our workshop app, and we'll actually deploy it onto the Cloudflare Developer Platform.Finally, we'll build out our app a little further, using D1 (our serverless SQL database) to really show off the React Server Component's power when combined with Smart Placement.You should come away from this workshop with a greater understanding of how React Server Components work (both behind-the-scenes and also how you as a developer can use them day-to-day), as well as insight into some of the new deployment patterns that are now possible after recent innovations in the platform space.
Building Reusable Server Components in NextJS
React Summit US 2023React Summit US 2023
88 min
Building Reusable Server Components in NextJS
Workshop
Will Bishop
Mettin Parzinski
2 authors
React continues to evolve their beta capability, React Server Components, and they're continuing to further develop them in partnership with frameworks like NextJS.In this workshop, attendees will learn what React Server Components are, how to effectively build and use them in NextJS, and focus on one of the major advantages of React/NextJS: reusability through components.We will also cover related beta technologies enabled by the `app` directory, such as nested layouts and server actions (alpha/experimental capability).Join us for this hands-on, 120 minute workshop!Technologies:
React, JavaScript/Typescript, NextJS, Miro
React Server Components Unleashed: A Deep Dive into Next-Gen Web Development
React Day Berlin 2023React Day Berlin 2023
149 min
React Server Components Unleashed: A Deep Dive into Next-Gen Web Development
Workshop
Maurice de Beijer
Maurice de Beijer
Get ready to supercharge your web development skills with React Server Components! In this immersive, 3-hour workshop, we'll unlock the full potential of this revolutionary technology and explore how it's transforming the way developers build lightning-fast, efficient web applications.
Join us as we delve into the exciting world of React Server Components, which seamlessly blend server-side rendering with client-side interactivity for unparalleled performance and user experience. You'll gain hands-on experience through practical exercises, real-world examples, and expert guidance on how to harness the power of Server Components in your own projects.
Throughout the workshop, we'll cover essential topics, including:- Understanding the differences between Server and Client Components- Implementing Server Components to optimize data fetching and reduce JavaScript bundle size- Integrating Server and Client Components for a seamless user experience- Strategies for effectively passing data between components and managing state- Tips and best practices for maximizing the performance benefits of React Server Components
Mastering React Server Components and Server Actions in React 19
React Advanced 2024React Advanced 2024
160 min
Mastering React Server Components and Server Actions in React 19
Workshop
Maurice de Beijer
Maurice de Beijer
Calling all React developers! Join us for an immersive 4-hour workshop diving deep into React Server Components and Server Actions. Discover how these game-changing technologies are revolutionizing web development and learn how to harness their full potential to build lightning-fast, efficient applications.
Explore the world of React Server Components, seamlessly blending server-side rendering with client-side interactivity for unmatched performance and user experience. Dive into React Server Actions to see how they combine client-side interactivity with server-side logic, making it easier to develop interactive applications without traditional API constraints.
Get hands-on experience with practical exercises, real-world examples, and expert guidance on implementing these technologies into your projects. Learn essential topics such as the differences between Server and Client Components, optimizing data fetching, passing data effectively, and maximizing performance with new React hooks like useActionState, useFormStatus and useOptimistic.
Whether you're new to React or a seasoned pro, this workshop will equip you with the knowledge and tools to elevate your web development skills. Stay ahead of the curve and master the cutting-edge technology of React 19. Don't miss out - sign up now and unleash the full power of React!