<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>Forem: Tim etc.</title>
    <description>The latest articles on Forem by Tim etc. (@timetc).</description>
    <link>https://forem.com/timetc</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F403642%2F6bf4c711-9657-48f4-b3f2-957221096f06.jpg</url>
      <title>Forem: Tim etc.</title>
      <link>https://forem.com/timetc</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://forem.com/feed/timetc"/>
    <language>en</language>
    <item>
      <title>A not useless guide to sustainable websites</title>
      <dc:creator>Tim etc.</dc:creator>
      <pubDate>Thu, 17 Oct 2024 13:43:03 +0000</pubDate>
      <link>https://forem.com/timetc/a-not-useless-guide-to-sustainable-websites-2bfo</link>
      <guid>https://forem.com/timetc/a-not-useless-guide-to-sustainable-websites-2bfo</guid>
      <description>&lt;p&gt;Let’s shut up about the planet, all that doomsday panic and start with why you would want to make your website sustainable? You are building the website or paying for it, what’s in it for you?&lt;/p&gt;

&lt;p&gt;More performance, more better. It will speed up your website, improving your productivity, your visitors will love the snappy website, resulting in higher conversion and Google gives you SEO bonus points. For high traffic sites it can even save money.&lt;/p&gt;

&lt;p&gt;Oh yeah, it will make the planet happy. Since IT has a growing impact on earth because it uses a lot of energy. If we all chip in we can make a big impact.&lt;/p&gt;

&lt;p&gt;You are not only helping the planet. It’s a valid business case.&lt;/p&gt;

&lt;h2&gt;
  
  
  Green hosting! Am I using that?
&lt;/h2&gt;

&lt;p&gt;Using sustainable energy for your applications and websites have a great impact since servers use a lot of energy and are turned on day and night. It’s a good place to start.&lt;/p&gt;

&lt;p&gt;Curious if you are using sustainable energy? The Green Web Foundation have a great tool to check that: &lt;a href="https://www.thegreenwebfoundation.org/green-web-check/" rel="noopener noreferrer"&gt;The Green Web Check&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;If not, that same foundation has &lt;a href="https://app.greenweb.org/directory/" rel="noopener noreferrer"&gt;a Green Web Directory&lt;/a&gt;. There you can find a lot off sustainable hosting providers, both local and global.&lt;/p&gt;

&lt;h2&gt;
  
  
  Is my website sustainable by using green hosting?
&lt;/h2&gt;

&lt;p&gt;It’s a great start, but there is more to it than that. Having a resource munching chunky boy website will use a lot of energy and transfer slowly, even on green hosting.&lt;/p&gt;

&lt;p&gt;Shall we get to the performance part where all the interesting things happen?&lt;/p&gt;

&lt;h2&gt;
  
  
  Optimising assets, small is fast
&lt;/h2&gt;

&lt;p&gt;For a lot of projects this is where you can make a big difference. Assets can be chunky and waste a lot of bandwidth and resources. A bunch of tips:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Minimise the amount of fonts you need and load, those hit hard (try to use max 3, but less is better).&lt;/li&gt;
&lt;li&gt;Use SVG’s where you can, they are small and scale well.&lt;/li&gt;
&lt;li&gt;Scale and crop images to the size you need, systems like WordPress have tooling for this and the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLImageElement/srcset" rel="noopener noreferrer"&gt;&lt;code&gt;srcset&lt;/code&gt;&lt;/a&gt; attribute can help switch size.&lt;/li&gt;
&lt;li&gt;Use modern formats for images and video’s, like WebP and WebM/AV1. Those offer improved compression and quality.&lt;/li&gt;
&lt;li&gt;Lazy loading images is a matter of using &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Element/img#loading" rel="noopener noreferrer"&gt;&lt;code&gt;loading="lazy"&lt;/code&gt;&lt;/a&gt;, just load what you need. You don’t need any scripts for this anymore.&lt;/li&gt;
&lt;li&gt;For video, only use autoplay if your really need to.&lt;/li&gt;
&lt;li&gt;Use compression (next up) and don’t load things you don’t need :)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Bonus for Tag Manager users: check all the third party scripts and tools you have. Do you use them? Do you get any value out of them? Periodically grooming is necessary. It’s not only about the assets you are loading, big data processing needs a lot of energy.&lt;/p&gt;

&lt;h2&gt;
  
  
  Serve it fast and small: cache and compression
&lt;/h2&gt;

&lt;p&gt;Enable compression. All modern webservers have it, make sure you use it. Modern options like Brotli are better, but even GZIP or Deflate can make a big difference in bandwidth. Mobile visitors will thank you even more.&lt;/p&gt;

&lt;p&gt;Caching depends on the project, but try to cache data that as close to the visitor as possible. For static assets like CSS/JS you could start with a proper cache header for the browser, reusing the downloaded file over and over.&lt;/p&gt;

&lt;p&gt;Do you have a content page that has more reads than updates? Serve it statically from disk or CDN. A framework like &lt;a href="https://astro.build/" rel="noopener noreferrer"&gt;Astro&lt;/a&gt; can statically generate to a CDN or a plugin like &lt;a href="https://wordpress.org/plugins/w3-total-cache/" rel="noopener noreferrer"&gt;W3 Total Cache&lt;/a&gt; can serve &lt;a href="https://wordpress.org/" rel="noopener noreferrer"&gt;WordPress&lt;/a&gt; pages from disk.&lt;/p&gt;

&lt;h2&gt;
  
  
  Keep your friends close, but your data closer
&lt;/h2&gt;

&lt;p&gt;Talking about CDN’s. Think about your visitors, where do they come from? Do you need a global distributed multi zone setup with edge workers to serve your local bakery website?&lt;/p&gt;

&lt;p&gt;Probably, but that’s your inner geek having fun. Don’t over use overkill solutions and keep your servers close to your users. It will save resources for both compute and transfer, keeping latencies low.&lt;/p&gt;

&lt;h2&gt;
  
  
  Stop using JavaScript, CSS is awesome!
&lt;/h2&gt;

&lt;p&gt;A lot of devs love writing JavaScript, doing all kinds of fancy animations, page transitions and other shenanigans. Not using vanilla JS or CSS, but big frameworks or libraries. That includes &lt;a href="https://jquery.com/" rel="noopener noreferrer"&gt;jQuery&lt;/a&gt;. You don’t need jQuery to get a DOM element and toggle a class! Don’t even get me started on &lt;a href="https://nextjs.org/" rel="noopener noreferrer"&gt;Next.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I got worked up, sorry. And honestly, those websites can be beautiful. The thing is that vanilla JS and CSS are great nowadays. Full of features that enable you to build all kinds of cool interactive components, animations and even page transitions.&lt;/p&gt;

&lt;p&gt;By using those you can write, ship and run less code. It’s all handled by your browser. Even smoother animations without blocking the main thread.&lt;/p&gt;

&lt;h2&gt;
  
  
  You don’t have to make it boring
&lt;/h2&gt;

&lt;p&gt;I’ve seen a lot of articles talking about using dark colours, system fonts and saying you should drop every little bell or whistle.&lt;/p&gt;

&lt;p&gt;That sounds like a public service announcement to make life dull. I don’t want that. Websites, apps, design, tech, should be fun, inspiring, alive.&lt;/p&gt;

&lt;p&gt;I’m not saying you have to build stupid features without any value that uses a lot of resources, be mindful, but don’t be boring.&lt;/p&gt;

&lt;h2&gt;
  
  
  Okay, bye.
&lt;/h2&gt;

&lt;p&gt;That’s it for now, but it is a topic that interests me. Expect more articles about the nitty gritty details. Any questions or tips? Please drop a comment or send me a DM on &lt;a href="https://x.com/timetcetera" rel="noopener noreferrer"&gt;Xwitter&lt;/a&gt; or &lt;a href="https://www.linkedin.com/in/timvanbergenhenegouwen/" rel="noopener noreferrer"&gt;LinkedIn&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>sustainability</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to use Angular i18n with the built in @angular/localize and XLF</title>
      <dc:creator>Tim etc.</dc:creator>
      <pubDate>Sat, 03 Sep 2022 14:58:19 +0000</pubDate>
      <link>https://forem.com/timetc/how-to-use-angular-i18n-with-the-built-in-angularlocalize-and-xlf-4c49</link>
      <guid>https://forem.com/timetc/how-to-use-angular-i18n-with-the-built-in-angularlocalize-and-xlf-4c49</guid>
      <description>&lt;p&gt;In &lt;a href="https://angular.io/" rel="noopener noreferrer"&gt;Angular&lt;/a&gt; you have the &lt;a href="https://angular.io/api/localize" rel="noopener noreferrer"&gt;@angular/localize&lt;/a&gt; package, which is Angular's own build in tooling for translations. This will be sufficient in most cases, it takes a few steps but it's easy to use.&lt;/p&gt;

&lt;p&gt;The translations are done through &lt;code&gt;aot&lt;/code&gt; compiling, all translations are compiled into the app ahead of time (when building your project). The upside is you have multiple builds of your app which enables different strategies for serving them and best of all: it has great performance. The downside is that it isn't optimized for dynamic logic, which is possible and I will explore in a later article.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Let's start! Add the localize package
&lt;/h2&gt;

&lt;p&gt;Assuming you have an Angular project already, let's start with adding the localize package to the project. If you haven't follow the &lt;a href="https://angular.io/guide/setup-local" rel="noopener noreferrer"&gt;Angular installation instructions&lt;/a&gt; and run &lt;code&gt;ng new your-project-name&lt;/code&gt; for a new project (you can replace the project name with a custom one, without using spaces)&lt;/p&gt;

&lt;p&gt;Angular's CLI makes this job very easy:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng add @angular/localize
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Make sure to use a recent version of Angular and the CLI, it will make it a lot easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Start marking translations
&lt;/h2&gt;

&lt;p&gt;Translating components is done by adding &lt;code&gt;i18n&lt;/code&gt; attributes to elements. This can be almost any element, ex. block elements like &lt;code&gt;h1&lt;/code&gt; and &lt;code&gt;p&lt;/code&gt;, even inline elements like &lt;code&gt;span&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;Format:
&lt;span class="nt"&gt;&amp;lt;element&lt;/span&gt; &lt;span class="na"&gt;i18n=&lt;/span&gt;&lt;span class="s"&gt;"{meaning}|{description}@@{id}"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Your text&lt;span class="nt"&gt;&amp;lt;/element&amp;gt;&lt;/span&gt;

Example:
&lt;span class="nt"&gt;&amp;lt;h1&lt;/span&gt; &lt;span class="na"&gt;i18n=&lt;/span&gt;&lt;span class="s"&gt;"{auth login headline|A warm welcome for the login screen@@authLoginHeadline"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;Welcome!&lt;span class="nt"&gt;&amp;lt;/h1&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the example you see the &lt;code&gt;i18n&lt;/code&gt; element with a value, this value has three sections:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;meaning: provide info about the meaning and intent&lt;/li&gt;
&lt;li&gt;description: ability to add context or additional information&lt;/li&gt;
&lt;li&gt;id: unique identifier&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All parts are all optional. Even the id, if you don't add one yourself it will be generated each time you export your translation source files in a later step. They will change every time you do this, so it will make maintenance of your translations a bit harder.&lt;/p&gt;

&lt;p&gt;It is best to do this on elements that wrap the text. So try not to translate a &lt;code&gt;div&lt;/code&gt; containing &lt;code&gt;p&lt;/code&gt; elements or an &lt;code&gt;ul&lt;/code&gt; containing &lt;code&gt;li&lt;/code&gt; elements.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; you can even use a &lt;code&gt;ng-template&lt;/code&gt; element when you don't want any additional DOM-elements, so you don't have to use &lt;code&gt;span&lt;/code&gt; elements if you need a few translations.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Generate translation source files
&lt;/h2&gt;

&lt;p&gt;A really satisfying step in the proces. Make the Angular CLI walk through all of your code and find &lt;code&gt;i18n&lt;/code&gt; attributes. From that it will generate a translation source file, with all translation sources.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;ng extract-i18n &lt;span class="nt"&gt;--output-path&lt;/span&gt; src/locale
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You now should have a XLF file in you &lt;code&gt;src/locale&lt;/code&gt; directory with a XML structure.&lt;/p&gt;

&lt;h3&gt;
  
  
  Tip: use &lt;a href="https://docs.npmjs.com/cli/v6/using-npm/scripts" rel="noopener noreferrer"&gt;npm scripts&lt;/a&gt;
&lt;/h3&gt;

&lt;p&gt;Make it easier on yourself, you don't have to remember this. Open up your &lt;code&gt;package.json&lt;/code&gt; file and add a line in the &lt;code&gt;scripts&lt;/code&gt; section:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"translate"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng extract-i18n --output-path src/locale"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now you can just run &lt;code&gt;npm run translate&lt;/code&gt; or &lt;code&gt;yarn translate&lt;/code&gt; for the same result. That's a lot easier for future self and your team members.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. Translate your app
&lt;/h2&gt;

&lt;p&gt;Working with this XLF file is quite hard to do from an editor, especially when you need to merge it with changes later on. That's why I made a tool called &lt;a href="https://whatwhat.app/?mtm_campaign=knowledge&amp;amp;mtm_source=dev.to&amp;amp;mtm_medium=article&amp;amp;mtm_content=angular-i18n-angular-localize-xlf"&gt;What?!&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqjjdbn7awto068wim7j.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcqjjdbn7awto068wim7j.png" alt="What?! i18n translation process with Angular's XLF/XLIFF files" width="800" height="477"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;a href="https://whatwhat.app/app?mtm_campaign=knowledge&amp;amp;mtm_source=dev.to&amp;amp;mtm_medium=article&amp;amp;mtm_content=angular-i18n-angular-localize-xlf"&gt;Open What?!&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Throw in your translation source file &lt;code&gt;src/locale/messages.xlf&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Translate the app to the targetted language&lt;/li&gt;
&lt;li&gt;Press 'Download' when you are done and save it to &lt;code&gt;src/locale/messages.[lang code].xlf&lt;/code&gt; (replace lang code with your language code, ex. nl or fr)&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; when you have a source and translation file, you can drag in both. It will automatically match the files and you can continue translating your app with ease. You can even see which sources have changed or filter on empty translations.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. Configuration of Angular
&lt;/h2&gt;

&lt;p&gt;Now we have to do some final configuration to make Angular use the XLF files you just created and compile them into your project in the build process. Open up &lt;code&gt;angular.json&lt;/code&gt; in your code editor, you can find it in your project's root folder.&lt;/p&gt;

&lt;p&gt;First we need to add the i18n configuration with the primary (source) language which is used with the text in your components.&lt;/p&gt;

&lt;p&gt;Add the following piece of JSON inside &lt;code&gt;your-project-name&lt;/code&gt; found in &lt;code&gt;projects&lt;/code&gt;, I have put it in between &lt;code&gt;prefix&lt;/code&gt; and &lt;code&gt;architect&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"i18n"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sourceLocale"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en-US"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"locales"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="nl"&gt;"nl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
      &lt;/span&gt;&lt;span class="nl"&gt;"translation"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"src/locale/messages.nl.xlf"&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do not forget to change &lt;code&gt;nl&lt;/code&gt; in this example, found in the object's name and filename. Change it to the language code you just translated your app to. You can also change the &lt;code&gt;sourceLocale&lt;/code&gt; if you haven't used English inside your app code.&lt;/p&gt;

&lt;p&gt;Now you can use the defined locales inside the build process, add this piece inside &lt;code&gt;configurations&lt;/code&gt; above &lt;code&gt;production&lt;/code&gt; (the one inside of &lt;code&gt;build&lt;/code&gt;).&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"nl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"localize"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="s2"&gt;"nl"&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The last thing we have to configure, being able to serve the development version of your app while using another language. You can do this inside &lt;code&gt;configurations&lt;/code&gt;, this time in &lt;code&gt;serve&lt;/code&gt;. Duplicate the &lt;code&gt;development&lt;/code&gt; configuration and rename it to the language code you want to use. Add &lt;code&gt;,[lang]&lt;/code&gt; at the end, so it will use the configuration we created before. For example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"nl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"browserTarget"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"project-name:build:development,nl"&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you copied the snippet above, do not forget to replace the &lt;code&gt;project-name&lt;/code&gt; with yours and language code (in both places).&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Party time!
&lt;/h2&gt;

&lt;p&gt;We now have generated language files, translated them and configured Angular to use those. Let's check out the end result!&lt;/p&gt;

&lt;h3&gt;
  
  
  Production build
&lt;/h3&gt;

&lt;p&gt;To make a build you can just use &lt;code&gt;ng build&lt;/code&gt; or &lt;code&gt;npm run build&lt;/code&gt;, just like before. You will notice a little difference inside the &lt;code&gt;dist&lt;/code&gt; folder, there is one build per language.&lt;/p&gt;

&lt;h3&gt;
  
  
  Serve development
&lt;/h3&gt;

&lt;p&gt;Run &lt;code&gt;ng serve --configuration=nl&lt;/code&gt; to serve your app, of course replace the language code with the one you used.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; you don't want to type this every time, at leas I don't. It's easier to make some npm scripts inside &lt;code&gt;package.json&lt;/code&gt; like before:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="nl"&gt;"start"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"npm run start:nl"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"start:nl"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng serve --configuration=nl"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="nl"&gt;"start:en"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"ng serve"&lt;/span&gt;&lt;span class="err"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So you can just run &lt;code&gt;npm start&lt;/code&gt; or &lt;code&gt;yarn start&lt;/code&gt; for the Dutch version in this case, or &lt;code&gt;npm run start:en&lt;/code&gt; (&lt;code&gt;yarn start:en&lt;/code&gt;) for the English one. A lot easier.&lt;/p&gt;

&lt;h2&gt;
  
  
  What's next?
&lt;/h2&gt;

&lt;p&gt;That's it, you now have a multi language Angular app! From now on you can continue working on your app, just repeat steps 2, 3 and 4. Making sure to mark all text in new components and generate new source files.&lt;/p&gt;

&lt;p&gt;Like I mentioned before, with a tool like &lt;a href="https://whatwhat.app/?mtm_campaign=knowledge&amp;amp;mtm_source=dev.to&amp;amp;mtm_medium=article&amp;amp;mtm_content=angular-i18n-angular-localize-xlf"&gt;What?!&lt;/a&gt; you can throw in your new source file and your existing translations. It will automatically merge them and show any changes. You can work through them and add any new translations as well. You only have to check changes, translate additions and include the result in your project. You are ready to build and launch!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tip:&lt;/strong&gt; do a walkthrough or PR review to make sure all text is going through the translation process.&lt;/p&gt;

&lt;h2&gt;
  
  
  That's it!
&lt;/h2&gt;

&lt;p&gt;This is all you need to get started with the Angular i18n module, there is a lot more to tell. You can follow me on &lt;a href="https://dev.to/timetc"&gt;Dev.to&lt;/a&gt; or &lt;a href="https://twitter.com/timetcetera" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; for new articles.&lt;/p&gt;

&lt;p&gt;Any questions or feedback? Let me know in the comments or hit me up on &lt;a href="https://twitter.com/timetcetera" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;!&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>i18</category>
      <category>angular</category>
      <category>productivity</category>
    </item>
    <item>
      <title>Angular with clean URL's using Apache's mod_rewrite</title>
      <dc:creator>Tim etc.</dc:creator>
      <pubDate>Sat, 07 May 2022 08:37:06 +0000</pubDate>
      <link>https://forem.com/timetc/angular-with-clean-urls-using-apaches-modrewrite-2bjb</link>
      <guid>https://forem.com/timetc/angular-with-clean-urls-using-apaches-modrewrite-2bjb</guid>
      <description>&lt;p&gt;In Angular you have a really nice router which takes care of all the things you need. Prefetching data, guarding specific routes and it will even lazy load modules. That all works out of the box, which I think is really awesome.&lt;/p&gt;

&lt;p&gt;When you are using Apache to serve your public/production environment you want to have beautiful clean URL's, for example 'whatwhat.app/page/3'. You need some additional configuration to make sure Angular's routing also kicks in when people visit those pages directly and not coming through the index/homepage.&lt;/p&gt;

&lt;p&gt;By default you will get a 404 page, because that file is not physically on the server. With mod_rewrite you can adjust this behavior in Apache, if that module is turned on (which is often the case). Configuration for Apache can be changed per folder using &lt;code&gt;.htaccess&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Apache's mod_rewrite and .htaccess
&lt;/h2&gt;

&lt;p&gt;Just copy the configuration below and drop it in a file named &lt;code&gt;.htaccess&lt;/code&gt; in the same folder containing your &lt;code&gt;index.html&lt;/code&gt; file. That's it!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check if mod_rewrite module is available
&amp;lt;IfModule mod_rewrite.c&amp;gt;

  # Turn the rewrite engine on and set URI base
  RewriteEngine On
  RewriteBase /

  # Serve files when they are found 
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -f [OR] 
  RewriteCond %{DOCUMENT_ROOT}%{REQUEST_URI} -d 
  RewriteRule ^ - [L] 

  # When file is not found, serve index.html instead
  RewriteRule ^ /index.html

&amp;lt;/IfModule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Optional: Run your Angular app from a sub directory
&lt;/h2&gt;

&lt;p&gt;You need some additional configuration for this, because Angular needs to know the path above it. The easiest way is to add a base tag in the &lt;code&gt;&amp;lt;head&amp;gt;&lt;/code&gt; tag of the &lt;code&gt;index.html&lt;/code&gt; like this: &lt;code&gt;&amp;lt;base href="/app/path/"&amp;gt;&lt;/code&gt;. Where the path should be adjusted to match yours of course, make sure it is the path above your Angular app (which should be ignored).&lt;/p&gt;

&lt;p&gt;Another way is to inject it, that can be easier if you have different configurations per environment (ex. dev/acc/prod). You can find more information in the documentation of &lt;a href="https://angular.io/api/common/APP_BASE_HREF" rel="noopener noreferrer"&gt;Angular APP_BASE_HREF&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;When using a sub directory also change that in your &lt;code&gt;.htacces&lt;/code&gt; like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;RewriteBase /&lt;/code&gt; should change to &lt;code&gt;RewriteBase /app/path/&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;RewriteRule ^ /index.html&lt;/code&gt; should be &lt;code&gt;RewriteRule ^ /app/path/index.html&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Make sure the &lt;code&gt;.htaccess&lt;/code&gt; file is in the same directory as Angular's &lt;code&gt;index.html&lt;/code&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What mod_rewrite will do for Angular
&lt;/h2&gt;

&lt;p&gt;For this of you who want a little background information about what is happening.&lt;/p&gt;

&lt;p&gt;What Apache does is serving files to your visitors when they ask for it. In the case of a homepage like 'whatwhat.app' it will serve the &lt;code&gt;index.html&lt;/code&gt;. With the configuration from the &lt;code&gt;.htaccess&lt;/code&gt; it will change a bit:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;When a file is found Apache will serve that to your visitor, which will make sure assets like js, css and images can be loaded. That also includes your Angular project. That is done with the &lt;code&gt;RewriteCond&lt;/code&gt; and &lt;code&gt;RewriteRule&lt;/code&gt;. Which will just use the URI from the request.&lt;/li&gt;
&lt;li&gt;After that there is another &lt;code&gt;RewriteRule&lt;/code&gt; as fallback and is only executed when a file is not found. It changes any URI to &lt;code&gt;/index.html&lt;/code&gt;. Which makes Apache look for the &lt;code&gt;index.html&lt;/code&gt; file and serve that instead. In that case your Angular app is served to your visitor.&lt;/li&gt;
&lt;li&gt;That is exactly what you want because when you move from 'whatwhat.app/' to 'whatwhat.app/page/3' Angular will do the work, but if you visit 'whatwhat.app/page/3' right away Apache will try to find it. Which it can't. By serving your app instead, the Angular router will get loaded and take over and resolve it afterwards.&lt;/li&gt;
&lt;li&gt;Any 404 page is a route that can't by found by the Angular router, which should also show an error page. That is up to you.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Even more possibilities
&lt;/h2&gt;

&lt;p&gt;You can use hashtags routing too, which won't be send to the server. That is an alternative in some cases and it can be good for security too (if you have params you don't want to send to the server). I will probably write about this in a separate article as well.&lt;/p&gt;

&lt;p&gt;Also using Angular's i18n and want some clean URL's? I have written an article called &lt;a href="https://whatwhat.app/articles/210526-angular-i18n-clean-urls-using-apache-mod_rewrite/?mtm_campaign=knowledge&amp;amp;mtm_source=dev.to&amp;amp;mtm_medium=article&amp;amp;mtm_content=angular-apache-mod_rewrite"&gt;Serve Angular i18n with clean URL's using Apache's mod_rewrite&lt;/a&gt;. To make translating Angular apps itself really easy you might like a tool I have made called &lt;a href="https://whatwhat.app/?mtm_campaign=knowledge&amp;amp;mtm_source=dev.to&amp;amp;mtm_medium=article&amp;amp;mtm_content=angular-apache-mod_rewrite"&gt;What?!&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;I am working on articles for other webservers and CDN's too, follow me on &lt;a href="https://dev.to/timetc"&gt;Dev.to&lt;/a&gt; to keep an eye out on those. Any tips or questions? Reach out to me in the comments or on &lt;a href="https://twitter.com/timetcetera" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt;. Thanks for reading!&lt;/p&gt;




&lt;p&gt;Photo by &lt;a href="https://unsplash.com/@andrewruiz?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Andrew Ruiz&lt;/a&gt; on &lt;a href="https://unsplash.com/s/photos/apache?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText" rel="noopener noreferrer"&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

</description>
      <category>angular</category>
      <category>javascript</category>
      <category>webdev</category>
      <category>tutorial</category>
    </item>
    <item>
      <title>Performance issues? Find your bottleneck with console.time()</title>
      <dc:creator>Tim etc.</dc:creator>
      <pubDate>Fri, 08 Oct 2021 06:59:27 +0000</pubDate>
      <link>https://forem.com/timetc/performance-issues-find-your-bottleneck-with-console-time-1bm1</link>
      <guid>https://forem.com/timetc/performance-issues-find-your-bottleneck-with-console-time-1bm1</guid>
      <description>&lt;p&gt;My, &lt;a href="https://dev.to/timetc/itch-scratch-and-share-1cnf"&gt;since a little while beautiful&lt;/a&gt;, app called &lt;a href="https://whatwhat.app/" rel="noopener noreferrer"&gt;What?!&lt;/a&gt; was a little slow when opening files. A lot slower since the version before the big redesign. When you changed a lot it is hard to find a starting point. What you can do about this? You already read the title so you know the answer. Tldr; &lt;a href="https://developer.mozilla.org/en-US/docs/Web/API/Console/time" rel="noopener noreferrer"&gt;just try it&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;The &lt;code&gt;console.log()&lt;/code&gt; function is something most JS developers know, you can output anything to the console (for Node as well as the browser). I think a lot of developers do not know about &lt;code&gt;console.time()&lt;/code&gt; though. Probably something you will use a lot less, but can be very useful.&lt;/p&gt;

&lt;p&gt;Okay, so let’s find that slow little bastard of a function. What you need to know:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;console.time(‘example’)&lt;/strong&gt; will start a timer, where you also give it a name. You can start multiple timers (simultaneously), if choose different names. It will not console anything though.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;console.timeLog(‘example’)&lt;/strong&gt; gives you the amount of elapsed milliseconds in the console. Make sure to start a timer first and same name. Tip: you can call it multiple times to see where the biggest time jumps in your process are made.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;console.timeEnd(‘example’)&lt;/strong&gt; will stop the timer and console log the amount of elapsed milliseconds.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Put the &lt;code&gt;console.time()&lt;/code&gt; at the start of your slow process and drop a few timeLog’s through the process. In places where different things are done, or maybe expect performance issues. Do not forget to stop the timer at the end.&lt;/p&gt;

&lt;p&gt;Do you have simultaneous tasks or a lot of steps? You can start multiple timers, measure the overal process and start separate timers for certain tasks/steps to get a better picture. Do whatever you need to see what piece of your code is taking too much time, just start and try.&lt;/p&gt;

&lt;p&gt;Hopefully you did find the son of a gun. Now you may have some ideas to implement it differently, maybe &amp;gt;1 options. Let’s implement them! Now you can try out things, make a duplicate function with a different implementation. Keep &lt;code&gt;console.time()&lt;/code&gt; in your code to measure the before/after.&lt;br&gt;
When you do have multiple solutions, check all of them out (or some of them) and see which one is the fastest. You already have the test bench set up, now is the time!&lt;/p&gt;

&lt;p&gt;Next up: pick your solution, remove your console functions because you don’t want them in production code, go to the store, buy confetti and celebrate! Your application got faster, congratulations :)&lt;/p&gt;

&lt;p&gt;Of course there are a lot more options for debugging performance, and a lot more tools to work with. I like this one because it is easy and accessible for everybody who is in need.&lt;/p&gt;

&lt;p&gt;It helped me to get my app &lt;a href=""&gt;What?!&lt;/a&gt; to be a lot faster. Especially on the larger translation files. Be careful with deep cloning large objects, lesson learned.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>performance</category>
      <category>angular</category>
      <category>codequality</category>
    </item>
    <item>
      <title>Serve Angular i18n with clean URL's using Apache's mod_rewrite</title>
      <dc:creator>Tim etc.</dc:creator>
      <pubDate>Wed, 26 May 2021 06:12:25 +0000</pubDate>
      <link>https://forem.com/timetc/serve-angular-i18n-with-clean-url-s-using-apache-s-modrewrite-38a4</link>
      <guid>https://forem.com/timetc/serve-angular-i18n-with-clean-url-s-using-apache-s-modrewrite-38a4</guid>
      <description>&lt;p&gt;In Angular you have some great internationalisation (&lt;a href="https://angular.io/guide/i18n" rel="noopener noreferrer"&gt;i18n&lt;/a&gt;) out of the box, which builds the nice compiled and minified bundle your used to. You have a compiled version per language. If you work with another framework which does the same thing (export a language per directory), this approach will work for you as well.&lt;/p&gt;

&lt;p&gt;My problem: the separate directories give you nasty URL's, something like whatwhat.app/en/. Okay, so that's just looks but it can also be a problem with sharing links. For example when user A shares a link with user B, but they have different native languages it will be annoying that the opened link does not have the language correct language for the receiver.&lt;/p&gt;

&lt;p&gt;In my case I wanted to make it a setting that the user can adjust, with a default language as a fallback. Easy to make and accessible because every page and link is always in your preferred language.&lt;/p&gt;

&lt;h2&gt;
  
  
  Make it work with .htaccess, mod_rewrite and cookies
&lt;/h2&gt;

&lt;p&gt;In the &lt;code&gt;.htaccess&lt;/code&gt; file I added notes about what is happening if you are curious about that. Make sure to adjust &lt;code&gt;example_locale&lt;/code&gt; which is the name of the cookie, &lt;code&gt;(en|nl|de)&lt;/code&gt; for the allowed options and &lt;code&gt;[E=LANG:en]&lt;/code&gt; will set the default language. To switch language, set a cookie and refresh the page from the app. That's it.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;# Check if mod_rewrite module is available
&amp;lt;IfModule mod_rewrite.c&amp;gt;

  # Turn the rewrite engine on and set URI base
  RewriteEngine On
  RewriteBase /

  # Prevent recursive rewrites
  RewriteCond %{ENV:REDIRECT_STATUS} 200
  RewriteRule ^ - [L]

  # Check for the cookie, get value or set to default
  RewriteCond %{HTTP_COOKIE} example_locale=(en|nl|de)
  RewriteRule .? - [E=LANG:%1,S=1]
  RewriteRule .? - [E=LANG:en]

  # Check if file exists, if so serve it
  RewriteCond %{DOCUMENT_ROOT}/%{ENV:LANG}%{REQUEST_URI} -f
  RewriteRule ^ %{DOCUMENT_ROOT}/%{ENV:LANG}%{REQUEST_URI} [L]

  # Serve index by default, also when a file isn't found
  RewriteRule ^ %{DOCUMENT_ROOT}/%{ENV:LANG}/index.html

  # Disable browser caching to prevent serving old versions
  # It also solves issues when switching language
  &amp;lt;FilesMatch "\.(html|htm|js|json)$"&amp;gt;
    &amp;lt;IfModule mod_headers.c&amp;gt;
      FileETag None
      Header unset ETag
      Header unset Pragma
      Header unset Cache-Control
      Header unset Last-Modified
      Header set Pragma "no-cache"
      Header set Cache-Control "max-age=0, no-cache, no-store, must-revalidate"
      Header set Expires "Mon, 10 Apr 1972 00:00:00 GMT"
    &amp;lt;/IfModule&amp;gt;
  &amp;lt;/FilesMatch&amp;gt;

&amp;lt;/IfModule&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To be honest, it has a downside. Caching is pretty much turned off. If you don't, the user can not switch languages after changing the cookie. Because the reload will hit the cache and serve the file for the old language. That is also the upside, you will have a bit more bandwith and load time, but if your product moves fast your visitors will likely be on the most recent version too.&lt;/p&gt;

&lt;p&gt;When that's okay and you want to make your load times faster, look into lazy loading if you haven't already. It will split up your application and make the initial load much smaller. Only loading additional parts of the application when needed. &lt;/p&gt;

&lt;p&gt;Still angry with me? Please, I have one more option. You can also make multiple builds and combine them. The Angular build process creates the one hash for the build, for all languages. By doing this you have different hashes per language. Removing &lt;code&gt;|js|json&lt;/code&gt; in the example above will make sure js/json files are cached, but will always fetch the &lt;code&gt;index.html&lt;/code&gt; file and therefor load the prefered language. A bit more work to fix your CI, but still.&lt;/p&gt;

&lt;p&gt;That's how I use Apache to serve different languages of my Angular app. Let me know if you have any questions, I am happy to help. Feedback is welcome too! I am pretty new to this writing thing. You can also reach out to me on &lt;a href="https://twitter.com/timetcetera" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; 🙂&lt;/p&gt;

&lt;p&gt;If you want to make your translation process easier and less time consuming, I made a tool for myself to let me focus on the translations. &lt;a href="https://whatwhat.app/" rel="noopener noreferrer"&gt;What?!&lt;/a&gt; Yeah, that's the name, you can use it too if you want.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>angular</category>
      <category>i18n</category>
      <category>apache</category>
    </item>
    <item>
      <title>Itch? Scratch! (and share)</title>
      <dc:creator>Tim etc.</dc:creator>
      <pubDate>Mon, 26 Apr 2021 22:56:51 +0000</pubDate>
      <link>https://forem.com/timetc/itch-scratch-and-share-1cnf</link>
      <guid>https://forem.com/timetc/itch-scratch-and-share-1cnf</guid>
      <description>&lt;p&gt;Three years ago. It is a nice summer day with a soft breeze and it hasn't rained in days. I am at the office, working. It already sounds like a nice story, but honostly I don't know what kind of day it was three years back. What I do know is that I was at the office and that we started a new project (called &lt;a href="https://hoorayhr.io/" rel="noopener noreferrer"&gt;HoorayHR&lt;/a&gt;).&lt;/p&gt;

&lt;p&gt;Angular would be the front-end framework and ambitions bigger than just the Dutch language, therefor we needed internationalisation. Which Angular has i18n for, works out of the box and it works well. The only downside, the process for creating them was really annoying. This is where the itching starts.&lt;/p&gt;

&lt;p&gt;New translations? Good luck finding them all, adding them to your existing translation file and don't forget to translate anything.&lt;/p&gt;

&lt;p&gt;Any source text changed? You probably won't notice. That's just waiting for a mistake to be made.&lt;/p&gt;

&lt;p&gt;The process was hard and time consuming, it's easy to make mistakes and I had no focus on the actual text (XML is noisy). You just want to know what you should translate, knowing all changes have been accounted for and that nothing is missing.&lt;/p&gt;

&lt;p&gt;First thing I did: search the world wide web for a solution. Back then, I found a desert. In general there was a lot of stuff on the internet to find, sadly nothing related to this problem. Maybe somewhere, but not for me to find. Being a programmer and builder of digital products the first thing you think is "How hard can it be?" and you start hacking away.&lt;/p&gt;

&lt;p&gt;That's the most fun part about creating things. Have an idea, dive into it, research new topics, collect some useful things and put things together. You make visual progress quickly and learn new things. It feels a bit like crafts back in the day at primary school. Taking some paper, glue, spend a bit of time and be happy about making something awesome.&lt;/p&gt;

&lt;p&gt;I was in the flow, the result was a really useful tool that our team have been using for years now, it saved a lot of time and mistakes. Time well spent. It also hurts your eyes because it is ugly as a naked cat, that is just a bonus. The itch has been scratched.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs44b0m8ydkxhx9qgnek1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fs44b0m8ydkxhx9qgnek1.png" alt="What?! prototype screenshot translation" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Aside from some quirks you need to know, it actually works really well. You just drop in your stuff and you do your thing. Focus on the actual copy.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwebgtdg41f8bx6sgpkti.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwebgtdg41f8bx6sgpkti.png" alt="What?! prototype screenshot empty state" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now, a few years later, I was curious what the new options would be. To my surprise there are some new projects, but not a whole lot. Most of them lack the focus and simplicity. That's when I decided to share my creation with the world. I figured that it could scratch some more itch, helping digital creators like you to focus on creating great products without unnecessary distractions.&lt;/p&gt;

&lt;p&gt;A nice opportunity to fix some quirks and do some design work to make it actually look nice. Something I wanted to do for a long time. As much as I like ugly UI's, I like good looking interfaces even more.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtrphmpsy3ufdxbgaak2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media.dev.to/cdn-cgi/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgtrphmpsy3ufdxbgaak2.png" alt="What?! tool screenshot translation" width="800" height="466"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;I am quite happy with the result, you can check it out at &lt;a href="https://whatwhat.app/" rel="noopener noreferrer"&gt;whatwhat.app&lt;/a&gt;! There are some details I want to fix and along the way I got even more ideas for improving the translation process. If you use Angular's i18n and/or XLIFF/XLF files, &lt;a href="https://whatwhat.app/app/" rel="noopener noreferrer"&gt;take it out for a spin&lt;/a&gt; 🙂&lt;/p&gt;

&lt;p&gt;Please let me know if you have feedback. You can reach out to me in the comments or on Twitter &lt;a href="https://twitter.com/timetcetera" rel="noopener noreferrer"&gt;@timetcetera&lt;/a&gt;. I love to hear what you think.&lt;/p&gt;

</description>
      <category>javascript</category>
      <category>angular</category>
      <category>i18n</category>
      <category>sideprojects</category>
    </item>
  </channel>
</rss>
