The other methods listed here work great, but I prefer not to use them, as it means that you need to add another translation file in the language of your source text, or else the original source text won't display. For example, if you change:
<mat-card *ngFor="let user of usersList">
<span>{{user}}</span>
</mat-card>
to:
<mat-card *ngFor="let user of usersList">
<span>dummy {user.role, select, admin {admin}}</span>
</mat-card>
The span text won't display properly unless you have a translation file that contains your source text with the target translation in the original language. This just creates extra work in my view, and also makes the html code look messy.
I prefer to add the localisation tags directly to the 'users' variable, like so:
usersList= [
{
name: $localize`Admin`,
},
{
name: $localize`Other`,
},
]
You can then generate your messages file and add the target translation below the source using the methods outlined by the other users on this post. Using this method, you can build your app normally without any localize option and it will still work.
Note that, for this method though, unike the other methods described on this post, you'd have one trans-unit per item.
Notice also that the quotation marks are ``, not ''. It will only work if you use template literals.
If you want to add custom ids, descriptions and meanings, you'd use this method:
name: $localize`:meaning|description@@customid:Admin`,
Finally, if your data is coming from the backend and you can't add the $localize tag to it, you can create a function that loops through the data in your ts component after retrieving it and adds the $localize tag to each necessary item.
I hope this helps!