views.json
Overview
views.json is the main configuration file of a Purple Experience application. It defines every page (view) the app can show, what components it renders, and what data it loads. It also defines redirects and global data that apply to all views. The file is an array of ViewConfig, RedirectConfig, and GlobalConfig entries.
When to use this
Edit views.json whenever you need to add a new page to the app, change what a page renders, configure SEO metadata, set up server-side cache behavior, or define URL redirects. All component and data source configuration lives in this file.
Basic Example
[
{
"globalData": [
{
"type": "json",
"contextKey": "experienceConfig",
"data": "resource://dynamic/storefront/assets/data/experience-config.json"
}
]
},
{
"path": "home",
"name": "home",
"appBar": "default",
"navigation": "bottom",
"content": [
{
"type": "list",
"template": "vertical",
"dataSource": {
"type": "content",
"contextKey": "articles",
"batchSize": 10
},
"content": {
"type": "content",
"template": "card"
}
}
]
},
{
"path": "article/:contentId",
"name": "article-detail",
"postView": {},
"content": [{ "type": "content-body", "template": "full" }],
"seo": {
"og_title": "$context.content.title",
"og_description": "$context.content.description"
}
},
{
"path": "old-home",
"redirectTo": "home"
}
]The first entry (with globalData) loads configuration data once on startup, available everywhere as $global. The second entry is the home view. The third is a post view (article detail). The fourth is a redirect. ßaq21^
Configuration
ViewConfig — a page definition
Property | Type | Default | Description |
|---|---|---|---|
path | string | — | Required. URL path for the view. Supports path parameters (:paramName). First matching view wins |
name | string | — | Required. Internal name used for tracking and navigation |
content | ComponentConfig[] | — | Required. Array of components to render on the page |
appBar | string | — | Key of the app bar to display. null hides the app bar |
navigation | string | — | Key of the tab navigation to display. null hides navigation |
data | DataSourceConfig[] | — | Data sources loaded when the view opens — results go into $context |
postView | object | — | Marks this view as a post/bundle detail view. |
| |||
title | string | — | Browser tab title. Defaults to the URL |
seo | object | — | SEO meta tags — see Seo Configuration belowConfiguration below |
cache | object | — | SSR cache-control settings — see Cache Configuration belowCache Configuration below |
pullToRefresh | object | — | Enables pull-to-refresh gesture on the view |
errorMessage | string | VIEW_ERROR | Translation key for the error message if the view fails to load |
errorButtonLabel | string | VIEW_ERROR_BUTTON | Translation key for the reload button label on error |
pageConfigs | object | — | Page-level ad configuration (e.g. Traffective) |
viewTrackingParams | object | — | Additional tracking parameters sent with view tracking events |
jsonLD | string | — | JSON-LD structured data string for SEO |
errorPage | boolean | false | Marks this view as the error/404 page |
jumpToContentButton | object | — | Configuration for the "jump to content" accessibility button |
SEO Configuration
The seo property sets HTML <meta> tags. All values support $context interpolation.
"seo": {
"og_title": "$context.content.title",
"og_description": "$context.content.description",
"og_image": "$context.content.thumbnails.default",
"robots": "index, follow"
}- Keys prefixed with og_ are set as <meta property="og:..." content="...">
- Keys prefixed with article_ are set as <meta property="article:..." content="...">
- All other keys are set as <meta name="..." content="...">
- canonical and og_url are set automatically — do not configure them here
- robots is only applied on custom domains. On preview instances, noindex, nofollow is always used
Cache Configuration
The cache property controls SSR cache-control headers. All values are in seconds as strings.
"cache": {
"maxAge": "60",
"staleWhileRevalidate": "3600",
"staleIfError": "86400"
}Property | Default | Description |
|---|---|---|
maxAge | "60" | How long the response is considered fresh (1 minute) |
staleWhileRevalidate | "3600" | How long to serve stale content while revalidating (1 hour) |
staleIfError | "86400" | How long to serve stale content if the origin errors (1 day) |
postView: content detail views
Setting postView tells the system this view renders a content detail page. Without it, the URL resolver must decide the view.
"postView": {
"postType": "article"
}If postType is omitted or empty, the view is used as a fallback for any content type that has no dedicated view.
RedirectConfig: URL redirects
{
"path": "old-path/:id",
"redirectTo": "new-path/:id",
"statusCode": 301,
"condition": {
"value": "$context.platform",
"operation": "EQUALS",
"compareValue": "WEB"
}
}Property | Type | Description |
|---|---|---|
path | string | URL path this redirect listens to |
redirectTo | string | NavigateActionConfig | The target path or action |
condition | object | Optional. Only redirects when true |
statusCode | number | HTTP status code for SSR redirects (default: 301) |
GlobalConfig: app-wide data
A GlobalConfig entry (identified by having a globalData key) loads data sources once at startup. The results are available via $global.<contextKey> across all views. Internet connectivity is required to fetch that data.
{
"globalData": [
{
"type": "json",
"contextKey": "appSettings",
"data": "resource://dynamic/storefront/assets/data/settings.json"
}
]
}Access it anywhere in views.json as $global.appSettings.myProperty.
Path parameters
Path parameters (:paramName) are automatically resolved to their API objects if recognized (e.g., :publicationId resolves the publication from the Catalog API). They are also available raw in $context.pathParams.paramName.
pullToRefresh
"pullToRefresh": {
"enabled": true,
"threshold": 80
}When enabled, a pull-down gesture on mobile triggers a full-view refresh (all data sources reload, metadata updates). This also happens automatically on app resume and after login/purchase.
Testing Notes / Edge Cases
- data sources vs. component data sources: data on a view loads data before the view renders. Component-level dataSource loads when the component is mounted. Use data for things every component on the page needs (e.g., the current publication). Use the component dataSource for list-specific data.
- SEO on client-side navigation: SEO meta tags are applied on every navigation, including client-side. The robots meta tag is not set on preview instances regardless of configuration.
- Cache only affects SSR: The cache settings control the HTTP Cache-Control header sent by the SSR server. They have no effect on client-side navigation.
- errorPage view: Only one view should be marked as errorPage: true. It is shown when any route match fails.
- Global data timing: globalData sources load before any view renders. If they are slow, the entire app startup is delayed. Load only what is truly needed on every page.