# developer Lightning Web Runtime (lwr-node) - Full Documentation
# @lwrjs/i18n
The [i18n API](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Internationalization) lets you add internationalization support to your Lightning Web Runtime on Node.js (LWR-JS) application. Based on a user's locale, you can use this package to:
- Translate strings into different languages
- Load different content on a page
- Translate user-inputted text
## Set Supported Locales in lwr.config.json
For LWR-JS, you have to format your locales as [UTS Locale Identifiers](https://www.unicode.org/reports/tr35/tr35-59/tr35.html#Identifiers). A locale identifier has the structure `language-region-script`. The `language` value is required while `region` and `script` are optional.
For example, the `en-US` identifier refers to English (`en`) spoken in the United States (`US`). The `en` identifier only refers to English without a specific geographical region.
To set which locales your application supports, create an `i18n` section in `lwr.config.json` and add a subsection called `locales`. To set the default locale for your site's content, create a `defaultLocale` subsection and set it to a single locale.
```
{
"i18n": {
// These are all the locales you want to support in your application
"locales": [{ "id": "en-US" }, { "id": "fr" }, { "id": "nl-NL", "fallback": "fr" }],
// This is the default locale you want to be used when visiting
// a non-locale prefixed path e.g. `/hello`
"defaultLocale": "en-US"
}
}
```
## Handle Locales with URI Patterns
To implement the locale rules that you created in [Set Supported Locales in lwr.config.json](#set-supported-locales-in-lwrconfigjson), you have to set up a URI pattern for handling locales. With LWR-JS, you can choose from path prefix routing and custom routing.
### Routing with Path Prefixes
Path prefix routing adds locale information to the user's URL. To use path prefix routing in your site, add `"uriPattern": "path-prefix"` to the `i18n` section of `lwr.config.json`.
For example, let's say the site `MyExampleSite` uses the following `i18n` configuration.
```
{
"i18n": {
// Supported locales: en-US, fr, nl-NL
"locales": [{ "id": "en-US" }, { "id": "fr" }, { "id": "nl-NL", "fallback": "fr" }],
"defaultLocale": "en-US",
// Use path prefix routing
"uriPattern": "path-prefix"
},
"routes": [
{
"id": "blog",
"path": "/blog",
"rootComponent": "demo/blog"
}
]
}
```
This site's URL is `https://myexamplesite.com`. It has the route `/blog`, which supports these URLs.
- `https://myexamplesite.com/blog`
- `https://myexamplesite.com/fr/blog`
- `https://myexamplesite.com/nl-nl/blog`
Although the `MyExampleSite` website registers each route with the default locale prefix, users that try to access those URLs (like `https://myexamplesite.com/en-us/blog`) get redirected to that URL without the prefix (`https://myexamplesite.com/blog`).
### Custom Locale Routing
If you don't set `uriPattern` in `lwr.config.json`, you have to use the `:locale` token in your `routes` configuration to define how URLs represent localized pages.
Here's an example of a config file for a site with a `/blog` route that uses custom URI routing.
```
{
"i18n": {
// Supported locales: en-US, fr, nl-NL
"locales": [{ "id": "en-US" }, { "id": "fr" }, { "id": "nl-NL", "fallback": "fr" }],
"defaultLocale": "en-US"
// "path-prefix" isn't set
},
"routes": [
{
"id": "blog",
"path": "/blog",
"rootComponent": "demo/blog"
},
// `blog-localized` sets up URL path for a dynamic locale value
{
"id": "blog-localized",
"path": ":locale/blog",
"rootComponent": "demo/blog"
}
]
}
```
## Access Locales with API Calls
If you want your API calls to have access to locale information, the following objects have a `locale` property that you can reference.
### page
The page information object (`page`) includes a locale property that you can use in your [template](https://developer.salesforce.com/docs/platform/lwr/guide/lwr-templates.md).
```
```
### SsrRequestContext
The `SsrRequestContext` object also contains the `locale` property.
When a component is server-side rendered (SSRed), LWR-JS calls the [`getServerData()`](https://developer.salesforce.com/docs/platform/lwr/guide/lwr-enable-ssr-site.md#load-data-during-ssr) hook. This function returns public properties to the component.
```
export async function getServerData(context: SsrRequestContext): Promise {
// This is called to fetch data when the component is SSRed
const topic = context.params.topic;
const locale = context.locale;
const response = await fetch(
`https://www.googleapis.com/books/v1/volumes?q=subject:${topic}&langRestrict=${locale}`,
);
const data = await response.json();
return { props: { data, ...context.params } };
}
```
### lwr/environment
Only in LWR-JS, the `lwr/environment` module contains the current locale in the `locale` value. `locale` doesn't get populated within the Salesforce platform, but you can import it like this:
```
import { locale } from 'lwr/environment';
```
# @lwrjs/security
[HTTP security headers](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers#security) guard your site against malicious code injections and cross-site scripting (XSS) attacks. You can implement security headers for your LWR site on a route-by-route basis using the `@lwrjs/security` package.
`@lwrjs/security` exposes a [default route handler](#default-route-handler) and a [security wrapper](#security-wrappers), both of which apply a set of default security headers. To customize these headers, modify the corresponding header configuration objects.
## Usage
To add this package to your project, run `npm install @lwrjs/security` on the command line. Implement this package for a route via the default handler or a security wrapper.
## Default Route Handler
The `@lwrjs/security` route handler matches the [RouteHandlerFunction](https://developer.salesforce.com/docs/platform/lwr/guide/lwr-routing-server.md#route-handler-functions) interface.
```
type RouteHandler = (ViewRequest, HandlerContext) => Promise;
```
It's exposed as the default export.
```
export { default } from '@lwrjs/security';
```
To use the default handler for a route, set `@lwrjs/security` as the route handler in `lwr.config.json`.
```
{
"routes": [
{
"id": "home",
"path": "/",
"rootComponent": "examples/example",
"routeHandler": "@lwrjs/security",
},
]
}
```
To modify a security header in the default route handler, set the corresponding header configuration object in the `routeHandler` section. You can disable a header by setting its configuration object to `false`. For more information about default headers and header configuration, skip ahead to [Headers](#headers).
```
"routeHandler": ["@lwrjs/security", {
"contentSecurityPolicy": "default-src 'self';base-uri 'self'; script-src 'self'",
"referrerPolicy": false,
"xXSSProtection": false
}]
```
## Security Wrappers
The `@lwrjs/security` route handler wrapper `secure()` applies security headers to an existing route handler. The wrapper is exposed as a named export. It takes a route handler as an argument and returns a promise.
```
type RouteHandlerWrapper = (RouteHandlerFunction) => Promise;
```
`RouteHandlerReturnType` can be a `ViewResponse` or `ViewDefinitionResponse`. Each type of promise applies headers as follows:
- **ViewDefinitionResponse** - applies the default security headers with inline resource hashing.
- **ViewResponse** (HTML content) - applies the default security headers without resource hashing.
- **ViewResponse** (non-HTML content) - doesn't apply headers.
For example, this `routeHandler.ts` file passes the `routeHandler` into `secure()`. Since the `headers` section is empty, only the default headers are used.
```
import type { ViewDefinitionResponse } from '@lwrjs/types';
import { secure } from '@lwrjs/security';
function routeHandler(): ViewDefinitionResponse {
return {
// programmatically define the view configuration
view: {
rootComponent: 'example/home'
},
// set response headers
headers: {},
};
}
export default secure(routeHandler);
```
To modify a header for the default handler, configure the corresponding header configuration object in the route handler file. You can disable a header by setting its configuration object to `false`.
```
headers: {
"contentSecurityPolicy": "default-src 'self';base-uri 'self'; script-src 'self'",
"referrerPolicy": false,
"xXSSProtection": false
},
```
## Headers
The default route handler and security wrapper automatically enable the following security headers.
### Content-Security-Policy
The `Content-Security-Policy` header directs your site to load content from only approved sources. For a list of acceptable formats for source values, see [CSP Source Values](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/Sources#sources).
These are the default directives for the `Content-Security-Policy` header.
| Directive | Description | Default Source Value |
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------- |
| `default-src` | Set the default source value for all directives that don't have a value. | `'self'` |
| `base-uri` | Set approved sources that load content in the page's `` element. | `'self'` |
| `font-src` | Set approved sources that provide fonts. | `'self' https: data:;` |
| `form-action` | Set approved sources that a form can send information to. | `'self'` |
| `frame-ancestors` | Set approved sources that can embed your page (the current frame) into a container like `` on their site. | `'self'` |
| `img-src` | Set approved sources of images and icons. | `'self' data:;` |
| `object-src` | Set approved sources of `