{"id":8543,"date":"2021-11-01T14:13:28","date_gmt":"2021-11-01T13:13:28","guid":{"rendered":"https:\/\/via-internet.de\/blog\/?p=8543"},"modified":"2021-11-01T14:29:59","modified_gmt":"2021-11-01T13:29:59","slug":"angular-working-with-i18n","status":"publish","type":"post","link":"https:\/\/via-internet.de\/blog\/2021\/11\/01\/angular-working-with-i18n\/","title":{"rendered":"Angular | Working with I18N"},"content":{"rendered":"\n<p class=\"wp-block-paragraph\">In this post, you will learn how to get started with&nbsp;<a rel=\"noreferrer noopener\" href=\"https:\/\/angular.io\/guide\/i18n\" target=\"_blank\">Angular I18n<\/a>&nbsp;using ngx-translate, the internationalization (i18n) library for Angular. We will cover the following topics:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>setup new angular app<\/li><li><span style=\"color: initial;\">install required dependencies<\/span><\/li><li>add bootstrap as ui framework<\/li><li>create app with demo page and translation services<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">This will be the final result (click to show video). Source code  for this post is on <a href=\"https:\/\/github.com\/r14r\/Angular_Working-with_I18N\" target=\"_blank\" rel=\"noreferrer noopener\">GitHub<\/a>.<\/p>\n\n\n\n<figure class=\"wp-block-image size-large\"><a href=\"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/video.gif\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"687\" src=\"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/video-1024x687.gif\" alt=\"\" class=\"wp-image-8556\" srcset=\"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/video-1024x687.gif 1024w, https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/video-300x201.gif 300w, https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/video-768x515.gif 768w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/a><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"setup-new-angular-app\">Setup new Angular app<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\u279c ng new app\n\u279c cd app<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"add-required-modules\">Add required modules<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">\u279c npm install @ngx-translate\/core @ngx-translate\/http-loader rxjs --save<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"add-bootstrap-as-ui-framework\">Add Bootstrap as UI framework<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We need the libraries for Bootstrap and flag icons. Download the required files into your <code>asset\/vendor\/bootstrap\/5.3.1<\/code> folder:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a rel=\"noreferrer noopener\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.1.3\/dist\/css\/bootstrap.min.css\" target=\"_blank\">Bootstrap CSS<\/a><\/li><li><a rel=\"noreferrer noopener\" href=\"https:\/\/cdn.jsdelivr.net\/npm\/bootstrap@5.1.3\/dist\/js\/bootstrap.min.js\" target=\"_blank\">Bootstrap JS<\/a><\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Flags Icons need a CSS file with the corresponding images for the flags, so we use the archive from GitHub.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><a href=\"https:\/\/github.com\/lipis\/flag-icons\/archive\/refs\/heads\/main.zip\">Flags Icons Archiv<\/a>: https:\/\/github.com\/lipis\/flag-icons<\/li><\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Download and extract the archive into the folder <code>assets\/vendor\/flag-icons<\/code><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"current-folder-structure\">Current folder structure<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">This is our current folder structure:<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"374\" height=\"690\" src=\"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-4.png\" alt=\"\" class=\"wp-image-8559\" srcset=\"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-4.png 374w, https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-4-163x300.png 163w\" sizes=\"auto, (max-width: 374px) 100vw, 374px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"setup-application\">Setup Application<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">We choose the following structure for the HTML architecture.<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code><strong>index.html<\/strong><\/code> contains the required <code>css <\/code>and <code>js<\/code> files.<br>Also, the <code>&lt;app-root&gt;<\/code> component, which loads our app<\/li><li><code><strong>app.component.html<\/strong><\/code> contains the main structure of every page.<br>This includes header, navigation, place for main content and footer<\/li><li>The main content is inserted via the <code>&lt;router-outlet&gt;<\/code><\/li><\/ul>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"index-html\">index.html<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We will add the corresponding file in the main<code> index.html<\/code> in our project.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;!doctype html>\n&lt;html lang=\"en\" class=\"h-100\">\n\n&lt;head>\n  &lt;meta charset=\"utf-8\">\n  &lt;title>I18N&lt;\/title>\n  &lt;base href=\"\/\">\n  &lt;meta name=\"viewport\" content=\"width=device-width, initial-scale=1\">\n  &lt;link rel=\"icon\" type=\"image\/x-icon\" href=\"favicon.ico\">\n\n  &lt;link rel=\"stylesheet\" href=\"\/assets\/vendor\/bootstrap.min.css\">\n  &lt;link rel=\"stylesheet\" href=\"\/assets\/vendor\/flag-icons.min.css\">\n\n  &lt;link rel=\"stylesheet\" href=\"\/assets\/vendor\/bootstrap\/5.1.3\/css\/bootstrap.min.css\">\n  &lt;link rel=\"stylesheet\" href=\"\/assets\/vendor\/flag-icons\/css\/flag-icons.min.css\">\n\n  &lt;link rel=\"stylesheet\" href=\"\/assets\/css\/default.css\">\n\n&lt;\/head>\n\n&lt;body class=\"d-flex flex-column h-100\">\n  &lt;app-root class=\"h-100\">&lt;\/app-root>\n\n  &lt;script src=\"assets\/vendor\/bootstrap\/5.1.3\/js\/bootstrap.bundle.min.js\">&lt;\/script>\n&lt;\/body>\n\n&lt;\/html><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"app-component-html\">app.component.html<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">We borrow the main structure from the bootstrap example &#8216;<a rel=\"noreferrer noopener\" href=\"https:\/\/getbootstrap.com\/docs\/5.1\/examples\/sticky-footer-navbar\/\" target=\"_blank\">Sticky Footer with Navbar<\/a>&#8216; with some changes in the navigation bar.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;header>\n    &lt;nav class=\"navbar navbar-expand-md navbar-dark fixed-top bg-primary\">\n        &lt;div class=\"container-fluid\">\n            &lt;a class=\"navbar-brand\" href=\"#\">\n                &lt;img src=\"assets\/img\/logo-angular.png\" height=\"40px\" width=\"auto\">\n            &lt;\/a>\n            &lt;button class=\"navbar-toggler\" type=\"button\" data-bs-toggle=\"collapse\" \n                data-bs-target=\"#navbarCollapse\"\n                aria-controls=\"navbarCollapse\" \n                aria-expanded=\"false\"     \n                aria-label=\"Toggle navigation\">\n                &lt;span class=\"navbar-toggler-icon\">&lt;\/span>\n            &lt;\/button>\n            &lt;div class=\"collapse navbar-collapse\" id=\"navbarCollapse\">\n                &lt;ul class=\"navbar-nav me-auto mb-2 mb-md-0\">\n                    &lt;li class=\"nav-item\">\n                        &lt;a class=\"nav-link active\" aria-current=\"page\" href=\"#\">Home&lt;\/a>\n                    &lt;\/li>\n                &lt;\/ul>\n\n                &lt;div class=\"btn-group dropstart\">\n                    &lt;button class=\"btn btn-primary dropdown-toggle\" type=\"button\" \n                        id=\"dropdownFlags\"\n                        data-bs-toggle=\"dropdown\" aria-expanded=\"false\">\n                        &lt;span class=\"flag-icon flag-icon-{{currentlang}}\">&lt;\/span>\n                    &lt;\/button>\n                    &lt;ul class=\"dropdown-menu\">\n                        &lt;li *ngFor=\"let lang of languages\" [value]=\"lang\" \n                            (click)=\"useLanguage(lang)\">\n                            &lt;a class=\"dropdown-item\"\n                                [ngClass]=\"{'active': currentlang == lang}\">\n                                &lt;span class=\"flag-icon flag-icon-{{lang}}\">&lt;\/span>\n                                &amp;nbsp;\n                                {{lang | uppercase}}\n                            &lt;\/a>\n                        &lt;\/li>\n                    &lt;\/ul>\n                &lt;\/div>\n            &lt;\/div>\n        &lt;\/div>\n    &lt;\/nav>\n&lt;\/header><\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;main class=\"flex-shrink-0\">\n    &lt;div class=\"container\">\n        &lt;router-outlet>&lt;\/router-outlet>\n    &lt;\/div>\n&lt;\/main><\/pre>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;footer class=\"footer mt-auto py-3 bg-dark\">\n    &lt;div class=\"container\">\n        &lt;span class=\"text-muted\">(C) Ralph G\u00f6stenmeier&lt;\/span>\n    &lt;\/div>\n&lt;\/footer><\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"app-component-ts\">app.component.ts<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import { Component } from '@angular\/core';\nimport { TranslateService } from '@ngx-translate\/core';\n\nimport defaultLanguage from '..\/assets\/i18n\/de.json';\n\n@Component({\n    selector: 'app-root',\n    templateUrl: '.\/app.component.html',\n    styleUrls: ['.\/app.component.scss'],\n})\nexport class AppComponent {\n    title = 'I18N';\n\n    languages = ['us', 'de', 'fr', 'sp'];\n    currentlang = 'us';\n\n    constructor(private translate: TranslateService) {\n        this.currentlang = 'de';\n        translate.setTranslation(this.currentlang, defaultLanguage);\n        translate.setDefaultLang(this.currentlang);\n    }\n\n    ngOnInit(): void {}\n\n    useLanguage(language: string): void {\n        this.currentlang = language;\n        this.translate.use(language.toLowerCase());\n    }\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"app-module-ts\">app.module.ts<\/h2>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">import { NgModule } from '@angular\/core';\nimport { BrowserModule } from '@angular\/platform-browser';\nimport { HttpClient, HttpClientModule } from '@angular\/common\/http';\n\nimport { AppRoutingModule } from '.\/app-routing.module';\nimport { AppComponent } from '.\/app.component';\n\nimport { TranslateLoader, TranslateModule } from '@ngx-translate\/core';\nimport { TranslateHttpLoader } from '@ngx-translate\/http-loader';\n\nimport { HomePageComponent } from '.\/pages\/home\/component';\nimport { DemoPageComponent } from '.\/pages\/demo\/component';\n\n@NgModule({\n    declarations: [AppComponent, HomePageComponent, DemoPageComponent],\n    imports: [\n        BrowserModule,\n        AppRoutingModule,\n        HttpClientModule,\n        TranslateModule.forRoot({\n            loader: {\n                provide: TranslateLoader,\n                useFactory: HttpLoaderFactory,\n                deps: [HttpClient],\n            },\n        }),\n    ],\n    providers: [],\n    bootstrap: [AppComponent],\n})\nexport class AppModule {}\n\n\/\/ required for AOT compilation\nexport function HttpLoaderFactory(http: HttpClient): TranslateHttpLoader {\n    return new TranslateHttpLoader(http);\n}<\/pre>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"how-the-app-works\">How the app works<\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The translation is done with the <a href=\"https:\/\/github.com\/ngx-translate\/core\" target=\"_blank\" rel=\"noreferrer noopener\">ngx-translate<\/a> component.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Translation works with different JSON files (for each language a separate file), containing the required translation for each text to be displayed. Each  text is addressed with a name within the JSON file.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">So, the base structure of each JSON file is the following:<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"translation-files\">Translation files<\/h3>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"assets-i18n-de-json\">assets\/i18n\/de.json<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n  \"i18n-demo-header\": \"I18N Demo\",\n  \"header\": \"I18N Funktionalit\u00e4t in Angular\"\n}<\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"assets-i18n-de-json\">assets\/i18n\/us.json<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">{\n  \"i18n-demo-header\": \"I18N Example\",\n  \"header\": \"I18N Functionality in Angular\"\n}<\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">These translations could be used in a html file by using the translate pipe:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;h1>{{'header' | translate }}&lt;\/h1><\/pre>\n\n\n\n<p class=\"wp-block-paragraph\">More information and examples are <a href=\"https:\/\/github.com\/ngx-translate\/core\" target=\"_blank\" rel=\"noreferrer noopener\">here<\/a>.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Changing the language is done with the help of the TranslateService<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"inject-your-app-with-the-translateservice\">Inject your app with the TranslateService (in <code>app.component.ts<\/code>)<\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">constructor(private translate: TranslateService) {\n    translate.setDefaultLang('de');\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"inject-your-app-with-the-translateservice\">Change Language <\/h3>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">useLanguage(language: string): void {\n    this.translate.use(language.toLowerCase());\n}<\/pre>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"integrate-in-our-ui\">Integrate in our UI <\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">To easy switching the language, we have to do a few steps<\/p>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"add-a-dropdown-menu-to-our-navigation-bar\">Add a dropdown menu to our navigation bar.<\/h4>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"885\" height=\"196\" src=\"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-5.png\" alt=\"\" class=\"wp-image-8568\" srcset=\"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-5.png 885w, https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-5-300x66.png 300w, https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-5-768x170.png 768w\" sizes=\"auto, (max-width: 885px) 100vw, 885px\" \/><\/figure>\n\n\n\n<p class=\"wp-block-paragraph\">And switching the language is done by calling <code>useLanguage <\/code>within each menu item:<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"9\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;div class=\"btn-group dropstart\">\n    &lt;button class=\"btn btn-primary dropdown-toggle\" type=\"button\"\n        id=\"dropdownFlags\"\n        data-bs-toggle=\"dropdown\" aria-expanded=\"false\">&lt;span\n        class=\"flag-icon flag-icon-{{currentlang}}\">&lt;\/span>\n    &lt;\/button>\n    &lt;ul class=\"dropdown-menu\">\n        &lt;li *ngFor=\"let lang of languages\" [value]=\"lang\"\n            (click)=\"useLanguage(lang)\">\n            &lt;a class=\"dropdown-item\" \n                [ngClass]=\"{'active': currentlang == lang}\">\n                &lt;span class=\"flag-icon flag-icon-{{lang}}\">&lt;\/span>\n                &amp;nbsp;\n                {{lang | uppercase}}\n            &lt;\/a>\n        &lt;\/li>\n    &lt;\/ul>\n&lt;\/div><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"setup-a-list-for-all-menu-items\">Setup a list for all menu items:<\/h4>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;ul class=\"dropdown-menu\"><\/pre>\n\n\n\n<h4 class=\"wp-block-heading\" id=\"add-a-list-item-for-each-language-ngfor-let-lang-of-languages-containing-a-link-and-an-event-handler-for-the-click-event\">Add a list item for each language<\/h4>\n\n\n\n<p class=\"wp-block-paragraph\" id=\"add-a-list-item-for-each-language-ngfor-let-lang-of-languages-containing-a-link-and-an-event-handler-for-the-click-event\">Add items (<code>*ngFor=\"let lang of languages\"<\/code>) containing a link and an event handler for the click event.<\/p>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"generic\" data-enlighter-theme=\"\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">&lt;li *ngFor=\"let lang of languages\" [value]=\"lang\" (click)=\"useLanguage(lang)\"><\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In this post, you will learn how to get started with&nbsp;Angular I18n&nbsp;using ngx-translate, the internationalization (i18n) library for Angular. We will cover the following topics: setup new angular app install required dependencies add bootstrap as ui framework create app with demo page and translation services This will be the final result (click to show video). Source code for this post is on GitHub. Setup new Angular app Add required modules Add Bootstrap as UI framework We need the libraries for Bootstrap and flag icons. Download the required files into your asset\/vendor\/bootstrap\/5.3.1 folder: Bootstrap CSS Bootstrap JS Flags Icons need a CSS [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":8548,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_crdt_document":"","_jetpack_memberships_contains_paid_content":false,"footnotes":""},"categories":[90,38,86],"tags":[],"class_list":["post-8543","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-angular","category-javascript","category-web-framework"],"jetpack_featured_media_url":"https:\/\/via-internet.de\/blog\/wp-content\/uploads\/2021\/11\/image-1.png","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/posts\/8543","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/comments?post=8543"}],"version-history":[{"count":28,"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/posts\/8543\/revisions"}],"predecessor-version":[{"id":8582,"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/posts\/8543\/revisions\/8582"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/media\/8548"}],"wp:attachment":[{"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/media?parent=8543"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/categories?post=8543"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/via-internet.de\/blog\/wp-json\/wp\/v2\/tags?post=8543"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}