chris
chris

Reputation: 95

How to deploy an i18n Angular with Azure Static web app

I am working on a Angular 14 application. This application is localized @angular/localize. When I run the npm build, I added --localize. The folder structure created by the build is: dist -> app-name -> local (fr, en, de..)

I push the dist folder in a very simple Nodejs. It is working like a charm.

Now I want to deploy the application on Azure Static web app. I go to the portal, and I create the application. And now the build failed: Failed to find a default file in the app artifacts folder (dist/app_name). Valid default files: index.html,Index.html

I undedstand the reason. If I push a non i18n application, the deployment is Ok, as the build create only one index.html in dist/app_name. I tried:

When I use the command: ng build --configuration production --localize=en , angular deploy only the en localization. Therefore everything runs.

So my question is: is it possible to run an i18n angular on azure static web app without creating one static webapp for each locale? Many thanks

Upvotes: 1

Views: 1414

Answers (3)

ali-alo
ali-alo

Reputation: 31

A quick answer to your question is yes you can!

Here is how I did this with Angular v19, i18n, and Azure Static Web App.

  1. First, you need to configure the build command of your project. I have modified the npm run build command to include the --localize flag.
"scripts": {
    "ng": "ng",
    "start": "ng serve",
    "build": "ng build --localize",
    "watch": "ng build --watch --configuration development",
    "test": "ng test",
    "lint": "ng lint",
    "translate": "ng extract-i18n --format json --output-path src/locale"
  }
  1. Understand your build output structure. For me, the output folder was the following.
  • /dist
    • /client (this was the name of my angular app)
      • /browser (this will be a folder that you upload to Azure Static Web App)
        • /en (these two folders are the localizations my app supports)
        • /ru

If you stick with the default i18n documentation, you should have a similar output project.

  1. In the root folder of your project create a staticwebapp.config.json file that configures the behaviour of the Azure web app. You need it because your server will respond from the /browser folder and you probably want to redirect them to a default locale (which is en for me). So create a staticwebapp.config.json in the same folder where your package.json for the angular project is located. Later in the pipeline, we will include this file in the /browser folder.
{
  "routes": [
    {
      "route": "/",
      "redirect": "/en/index.html"
    },
    {
      "route": "/index.html",
      "rewrite": "/en/index.html"
    }
  ],
  "navigationFallback": {
    "rewrite": "/en/index.html"
  }
}

As you can see, I specifically picked en as my default locale. I fall back and redirect to that locale when the Azure Static Web App returns 404 or when users locale to the root path of my domain.

  1. Configure the Azure-generated YAML file. By default, Azure generates a file that builds and deploys an app in one step. You must change this and manually build the app with our custom configurations. Add the following steps to your pipeline before the deployment to Azure step:
 - name: Set up Node.js
        uses: actions/setup-node@v3
        with:
          node-version: '20.x'
      - name: Install dependencies and build project
        run: | # angular is my folder in the repository root project where I store front-end code (if your angular project and its package.json are located in the root folder of the GitHub repository remove "cd angular"
          cd angular
          npm ci
          npm run build
      - name: Ensure index.html exists in /browser
        run: | # You can put any content inside the index.html, but without this file Deployment to Azure won't succeed
          mkdir -p angular/dist/client/browser
          cd angular/dist/client/browser
          echo "<html><body><h1>Hello!</h1></body></html>" > index.html
      - name: Copy staticwebapp.config.json to /browser folder
        run: | # angular is my folder in the repository root project where I store front-end code
          cd angular
          cp staticwebapp.config.json dist/client/browser

Now in the pipeline tell Azure to just deploy instead of building and deploying. Make sure app_location is the location that contains your localization folders, index.html, and staticwebapp.config.json files. And make sure to disable the build process by setting skip_app_build parameter to true

name: Deploy
        id: deploy
        uses: Azure/static-web-apps-deploy@v1
        with:
          azure_static_web_apps_api_token: ${{ secrets.AZURE_STATIC_WEB_APPS_API_TOKEN_CALM_GROUND_00CF8EC0F }}
          action: "upload"
          ###### Repository/Build Configurations - These values can be configured to match your app requirements. ######
          # For more information regarding Static Web App workflow configurations, please visit: https://aka.ms/swaworkflowconfig
          app_location: "./angular/dist/client/browser" # App source code path
          github_id_token: ${{ steps.idtoken.outputs.result }}
          skip_app_build: true  # tell the azure not to build the app for us, we have already done this manually using Node
          ###### End of Repository/Build Configurations ######

Note: Your angular.json does not need extra configurations, but you need to make sure that index.html files in your locales have the href attribute of the base HTML tag set to their corresponding locales. This is a default Angular build configuration.

<!doctype html>
<html lang="en" dir="ltr">
<head><link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
  <meta charset="utf-8">
  <base href="/en/">  <!-- index.html inside of the /en folder-->
  <!-- More html content -->

Upvotes: 0

First of all you need your staticwebapp.config.json with the necessary redirects of your locales, you will have to decide which one is the default. I don't know if there is a way to configure the accept-language header for the routes.

{
    "routes": [
        {
            "route": "*.{js,json,css,jpg,png,ico,webmanifest}"
        },
        {
            "route": "/index.html",
            "rewrite": "/es-CL/index.html"
        },
        {
            "route": "/en-US/*",
            "rewrite": "/en-US/index.html"
        },
        {
            "route": "/it-IT/*",
            "rewrite": "/it-IT/index.html"
        },
        {
            "route": "/es-CL/*",
            "rewrite": "/es-CL/index.html"
        }
    ]
}

then you need to create an empty Index.html file in the root of the app (dist/index.html)

I do this by adding an Agent Job in your pipeline just before publishing the SPA:

steps:
- script: |
   echo "<html></html>" > index.html
   ls
  workingDirectory: '$(System.DefaultWorkingDirectory)/Your app dist'
  displayName: 'Command Line Script'

Upvotes: 2

Michael Odumosu
Michael Odumosu

Reputation: 95

Hey I was going to make a video but contact me I can help you out if you dont have time follow this doc I made

go to manage deployment token in static web apps in azure portal

also for localization you don't want to use angular localization, I much rather use '@ngx-translate'

  • you want to run the deploy command from the directory root
    • --env flag deploy to production
npx swa deploy ./dist/azureSWA  --deployment-token [Your deployment token] --env production

Upvotes: -1

Related Questions