MARK THOMPSON: Hm. I wish there was some way
for me to get my application to display in the
language of my users. Oh wait, there is. You want to find out how? Well, you know what to do. Stick around. [MUSIC PLAYING] Hey, friends. I'm Mark from the
Angular team, and I am thrilled to be back with
another crisp new video. Together we'll learn
about internationalization and Angular and
internationalize an application. This is going to be great. Let's go over some terms before
writing any code so that way we're all on the same page. If you're already familiar
with internationalization, you can skip ahead
to the next chapter. When talking about
making your app available in
different languages, you may hear the terms
internationalization and localization. Although these terms are
related, they are not the same. Let me explain. Internationalization, or
often abbreviated as i18n, is the process of
preparing and designing your app to support its
use in different languages and language dialects. This could include
enabling your application to support rendering
in different languages by separating the content
that will then be translated. Also, the preparation could
include updating your app to support bidirectional text-- that is, left to right
or right to left. Once you prepare your
app, the next step is to localize the application. Localization is the process
of building versions of your project for
your different locales. Wait, so what's a locale? A locale identifies a region
where people speak a language or language variant. For a given locale,
there's specific formatting for measurements of
time, numbers, and currency. There's also
translations of names, including time zones,
languages, and countries. Check out the description
for more resources and helpful links
containing information about locale settings. Locals take the format of
language ID hyphen locale extension-- for example, en-US
for English and the United States or fr-CA for
French and Canada. Here are a few more
things to consider. The internationalization
process technically only needs to happen
once, and then you can localize your application
to as many locales as needed without changing
your application code. If you expand your
application, you'll need to ensure that
those new pages have been internationalized. Now, teams may perform
the localization process multiple times to support
different locales. And depending on
the target language, it may be revealed
that the string sizes from one of the
locales may disrupt the UI. This can happen with languages
like German, for example. So be sure to review your UI. All right, great. With language
covered, let's go over what we'll do together today. We'll install our dependencies
to add support for localization and internationalization. We'll internationalize
our application. Then we'll localize
our application. Now here's the application
that we're going to localize. It represents an order
confirmation page in an e-Commerce app. All right, let's head
over to the code. First, let's get those
dependencies installed. We'll do that using the
Angular localize package. From the command
line in your project, type ng add @angular/localize. And when asked if we want
to proceed, reply yes. This package gives us the tools
to localize our application. While we're getting our
dependencies sorted, we'll also update angular.json. First, we'll specify which
locale we'll be supporting. In my example, I'm
going to use Spanish. Under projects,
our app name, I'm going to add the i18n property. Next, I will specify
the source locale property, which is our locale
used in the source code. So for this example,
it'll be en-US. Let's add another property
called locale and specify which locales this
application will support and where the translation
file will be stored. That will be
src/local/messages.es.xlf. We haven't created this file
yet, but that's coming up soon. Under architect, build, options,
let's add another localized property and give it the
value of an array with es-PR as the only element. This tells the
Angular which locale to build when it's time to
localize the application. Also, please note that
adding this property also allows us to preview a
specific locale within ngcert. We can't preview
multiple locales at the same time with ngcert,
so adding multiple locales to the array or setting
the property value to true will lead to an error when
running our application with the dev server. All right, our app
configuration is done. Great job. Up next, let's check out our
application and look for OTIs. That's Opportunities
To Internationalize. In our application, where
can we find some OTIs? This application features
quite a few strings that could be internationalized--
your order is on its way, thank you for shopping
with us and your order has been processed,
the table header's item quantity, date and
amount, and finally, the total amount text. We can also internationalize
the currency for total amount
and the date value. Is there anything else? Now, this one can
be easy to miss. If you said images,
then I want you to get that handle
right now because I have something for you. High five from me to you. That's right. The images will
have alt text that needs to be translated into
the language of our locale. Now that we know which
things to internationalize, let's go to the code again. In app.component.html,
let's start by updating the text
parts of the application. We'll mark these as
content that will be displayed in
the selected locale by adding the i18n attribute. In our case, we'll use the
basic form of the attribute, but developers can add
more metadata details like customized IDs and
context for translators too. Next, we'll use pipes
for the date and currency marked for translation. The date pipe and
currency pipe both support locale-specific
formatting by default. We'll take advantage
of the i18n attribute to mark the Alt text attribute
of the image for translation. The alt attribute isn't
the only option here. We can mark other attributes
for translations too. Before we move on
to the next step, let's use dollar sign localize
to mark the page title for translation in our component
class app.component.ts. And just like that,
we've internationalized our application. Let's go! Now for the good part. We're going to use the extract
i18n command with the Angular CLI to extract all of
the elements that have been marked for translation. In the command prompt, type
ngextract--i18n and then specify where the translation
file should live with the output path option. In this example, I'll add
source/locale, which matches the location from angular.json. In the locale folder
we just created, we now have our messages
file, which is great. But these messages are
in the original language. Here's what to do next. We're going to make a
copy of this file for each of our supported locales. I'm going to make a copy of
this file named messages.es.xlf. This is using the locale ID that
we specified in angular.json. At this point, we pass the
local files to the translator and then update our project
with the updated files. But for this example,
though, we're going to add the
translations ourselves. So in messages.es.xlf,
we find that each message from our project has a section. In that section, we find
the ID for the translation and the original text
under the source element. Our next step is to add a
sibling element to the source element called target. The target represents
the translated text for this locale. Let's make those updates now. Here's the moment of truth. Time to view our
localized application. From the command line,
we'll run ng serve. Now check our app
in the browser, and there we have it-- a fully
internationalized and localized application. So exciting. ng serve is just our
dev server, but we can build localized versions
of our app with ngbuild and pass the localized flag
to build all of our locales or leave it off to build
the locale specified in the build config in angular.json. I'm going to use a local
server to serve our build. Next, I'll go to localhost port
3000/es for a Spanish locale. And here we have it. We can also go to en-US for
the English locale and whatever other locale you configured
for this example. Right now, we can see the
changes in our local server. When it's time to
deploy the application, we'll want to configure the
server, the base href, and more to properly show the users
their preferred language. The Angular documentation
has some great information on how to set these
up, and you can find links in the description below. One final thing to note-- you may be wondering why we
need a version of our Web App for each locale. Why not follow patterns
defined by other solutions? Well, these are some
great questions. First thing to consider is
that the translation step is done as a part of
the post-build process. So your build times aren't
impacted by the localization step. Next, consider the
performance cost of changing the language of
your application in real time. To be able to change the
language without reloading the page, each
translation string will create a new binding. But most of the time, users will
not be changing the language, so the values of these
bindings will remain the same. Then, when change
detection runs, it'll have to check
all of the bindings even if you haven't
changed anything. And additionally, each binding
is an extra instruction which adds to the application bundle. To change the language
during runtime requires shipping the
translation library, which also increases your app size. Here's another consideration--
translation files aren't tree shakable. Again, let me explain. An application can have
thousands of translations strings for a given language. It's hard to know which
translations will be used and which won't for
a selected language. Applying the
translations at runtimes means that we load all of
the translation strings even if they aren't used
in your application. Because Angular does
build time localization, we'll only include the strings
that are used in the app. Now, there's a cost to the
Angular solution as well. You'll have to refresh
the page in order to see the translations whenever
your user chooses a new locale that your application supports. Now, every approach
has its trade-offs. Angular's build time
i18n is optimized for load and performance. We believe that users
don't change the locale too frequently. So a page reload once is
a reasonable trade off. And friends, if you do need to
load your translations at run time, there is a way to do it
using dollar sign localize. But this will only work once. If you're interested, I'm going
to link to the docs down below. All right, friends,
that does it for me. This has been a
lot of fun, and I hope that you've enjoyed
our time together today. This example project, links
to the official Angular internationalization
guide, and more are in the description
of this video. Like this video and
subscribe if you haven't, and until the
next time, friends, go build great apps. [MUSIC PLAYING]