The Render Runtime app is responsible for handling runtime execution of React apps in the VTEX IO Platform. Additionally, it exports:
- Helpful variables, such as
canUseDOM. - Hooks, such as
useRuntime. - React components, such as
Block(aliasExtensionPoint),Helmet,Link,NoSSRandwithRuntimeContext.
ℹ️ Tip: Run vtex setup --typings to add vtex.render-runtime types in your app. This way, IDEs will be able to provide autocomplete for variables and methods.
Check the following sections for more information on the objects exported by the Render Runtime app.
A boolean value that indicates whether the code is running in a browser environment (true) or in a Node/SSR environment (false).
ℹ️ Notice that the
canUseDOMvariable is especially useful in cases the components use DOM related data (e.g:documentorwindow).
Take the following usage example:
importReactfrom'react'import{canUseDOM}from'vtex.render-runtime'functionMyComponent(){constdata=canUseDOM
? window.localStorage.getItem('foo')
: ''return<div>Hello</div>}exportdefaultMyComponentThe useRuntime React hook is useful when creating components since it provides runtime contextual variables and methods.
For an example on its usage, check the following snippet:
importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){construntime=useRuntime()return<div>Hello</div>}Inside the runtime object you can have access to the following variables:
| Name | Type | Description |
|---|---|---|
account | string | The VTEX account name, (e.g., storecomponents). |
binding | object | An object containing the id and canonicalBaseAddress of the store binding. |
culture | object | An object containing culture, currency and locale information. |
deviceInfo | object | An object specifying the user device type (phone, desktop, tablet, or unknown). This data varies when the user resizes the window. |
getSettings | function | A function that, when called, returns the public settings of an app. |
hints | object | An object which specifies the user device type (phone, desktop, tablet, or unknown) based on the information provided by the CDN. Different from deviceInfo this data is static. |
history | object | A history object reexported from the history package. For further information, check this link. |
navigate | function | A function used in the client-side to define the navigation behaviour. |
page | string | The current page id (e.g., store.home). |
pages | object | Object containing all pages. The keys are the pages ids (e.g., store.home). |
route | object | Object containing data related to the current route, such as id, path, blockId and others. |
production | boolean | Points if the app is in a production workspace (true) or not (false). |
query | object | The URL query string values in a key-value format (e.g., { "foo": "bar" }). |
renderMajor | number | The major version of the Render Runtime app. |
rootPath | string | The store root path (e.g., /ar). If not specified, its value is undefined. |
setQuery | function | A function that can be called to set query string params. |
workspace | string | The current workspace name (e.g., master). |
Check the following section for usage examples on how to use the internal runtime variables.
importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ account }=useRuntime()return<div>Welcome to {account}</div>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ binding }=useRuntime()return<div>Canonical address is "{binding.canonicalBaseAddress}"</div>}exportdefaultMyComponentType:
interfaceBindingInfo{id: stringcanonicalBaseAddress: string}Example value:
{
"id": "aacb06b3-a8fa-4bab-b5bd-2d654d20dcd8",
"canonicalBaseAddress": "storetheme.vtex.com/"
}importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ culture }=useRuntime()return<div>Current active locale is: "{culture.locale}"</div>}exportdefaultMyComponentType:
interfaceCulture{availableLocales: string[]country: stringcurrency: stringlanguage: stringlocale: stringcustomCurrencyDecimalDigits: number|nullcustomCurrencySymbol: string|null}Example value:
{
"availableLocales": [],
"country": "USA",
"currency": "USD",
"language": "en",
"locale": "en-US",
"customCurrencyDecimalDigits": null,
"customCurrencySymbol": "$"
}importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ deviceInfo }=useRuntime()return<div>This page is being rendered on a "{deviceInfo.type}"</div>}exportdefaultMyComponentType:
interfaceDeviceInfo{isMobile: booleantype: 'phone'|'tablet'|'desktop'|'unknown'}Example value:
{
"isMobile": false,
"type": "desktop"
}importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ getSettings }=useRuntime()constsettings=getSettings('vtex.store')return<div>This is the store's name: "{settings.storeName}"</div>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ hints }=useRuntime()if(!hints.desktop){return<div>This is not a desktop</div>}return<div>This is a desktop</div>}exportdefaultMyComponentType:
interfaceHints{desktop: booleanmobile: booleantablet: booleanphone: booleanunknown: boolean}Example value:
{
"desktop": true,
"mobile": false,
"tablet": false,
"phone": false,
"unknown": false,
}importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ history }=useRuntime()consthandleClick=()=>{history.goBack()}return<buttononClick={handleClick}>Back</button>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ navigate }=useRuntime()consthandleClick=()=>{navigate({to: '/other-page'})}return<buttononClick={handleClick}>Go</button>}exportdefaultMyComponentFunction param:
interfaceNavigateOptions{fallbackToWindowLocation?: booleanhash?: stringpage?: stringparams?: anyquery?: anyreplace?: booleanrootPath?: stringscrollOptions?: false|{baseElementId: string,behavior: 'auto'|'smooth'left: numbertop: number}skipSetPath?: booleanto?: string}importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ page }=useRuntime()return<div>This is the current page id: "{page}"</div>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ pages, page }=useRuntime()return<div>This is the current page declarer: "{pages[page].declarer}"</div>}exportdefaultMyComponentExample value:
{
"allowConditions": true,
"context": null,
"declarer": "vtex.store@2.x",
"path": "/",
"routeId": "store.home",
"blockId": "vtex.store-theme@4.x:store.home",
"map": []
}
importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ route }=useRuntime()return<div>This is the current route full path: "{route.path}"</div>}exportdefaultMyComponentExample value:
{
"domain": "store",
"id": "store.home",
"pageContext": {
"id": "store.home",
"type": "route"
},
"params": {},
"path": "/",
"pathId": "/",
"queryString": {},
"breakpointStyles": [
{
"path": "/_v/public/vtex.styles-graphql/v1/style/vtex.store-theme@4.3.0$style.common.min.css",
"mediaQuery": "",
"type": "common"
},
{
"path": "/_v/public/vtex.styles-graphql/v1/style/vtex.store-theme@4.3.0$style.small.min.css",
"mediaQuery": "screen and (min-width: 20em)",
"type": "small"
},
{
"path": "/_v/public/vtex.styles-graphql/v1/style/vtex.store-theme@4.3.0$style.notsmall.min.css",
"mediaQuery": "screen and (min-width: 40em)",
"type": "notsmall"
},
{
"path": "/_v/public/vtex.styles-graphql/v1/style/vtex.store-theme@4.3.0$style.large.min.css",
"mediaQuery": "screen and (min-width: 64em)",
"type": "large"
},
{
"path": "/_v/public/vtex.styles-graphql/v1/style/vtex.store-theme@4.3.0$style.xlarge.min.css",
"mediaQuery": "screen and (min-width: 80em)",
"type": "xlarge"
}
],
"fonts": "/_v/public/vtex.styles-graphql/v1/fonts/7ead87572b7446c1ca01c45f5065665fc8cfd256",
"overrides": [
"/_v/public/vtex.styles-graphql/v1/overrides/vtex.product-list@0.28.2$overrides.css",
"/_v/public/vtex.styles-graphql/v1/overrides/vtex.minicart@2.56.0$overrides.css",
"/_v/public/vtex.styles-graphql/v1/overrides/vtex.store-theme@4.3.0$overrides.css"
],
"rootName": "store.home",
"ssr": true,
"styleMeta": {
"fontsHash": "7ead87572b7446c1ca01c45f5065665fc8cfd256",
"overridesIds": [
{
"id": "vtex.product-list@0.28.2$overrides.css"
},
{
"id": "vtex.minicart@2.56.0$overrides.css"
},
{
"id": "vtex.store-theme@4.3.0$overrides.css"
}
],
"themeId": "vtex.store-theme@4.3.0$style.min.css"
},
"blockId": "vtex.store-theme@4.x:store.home",
"canonicalPath": "/",
"metaTags": null,
"routeId": "store.home",
"title": null,
"varyContentById": false
}importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ production }=useRuntime()if(!production){return<div>This is not a production workspace</div>}return<div>This is a production workspace</div>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ query }=useRuntime()return<div>The current query strings are {JSON.stringify(query)}</div>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ renderMajor }=useRuntime()return<div>This page is rendered using vtex.render-runtime@{renderMajor}.x</div>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ rootPath }=useRuntime()if(!rootPath){return<div>The store doesn't have a rootPath set</div>}return<div>The store rootPath is "{rootPath}"</div>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ setQuery }=useRuntime()consthandleClick=()=>{setQuery({foo: 'bar'})}return<button>Set</button>}exportdefaultMyComponentimportReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ workspace }=useRuntime()return<div>This is the {workspace} workspace</div>}exportdefaultMyComponentBlock is a React component used to create Store Framework blocks.
For implementation details, take the following example.
ℹ️ Notice that the
Blockcomponent will always expect a specific blockid.
importReactfrom'react'import{Block}from'vtex.render-runtime'// or// import { ExtensionPoint } from 'vtex.render-runtime'functionMyComponent(){return(<div>
Foobar
<Blockid="my-other-block"/>{/* or <ExtensionPoint id="my-other-block" /> */}</div>)}exportdefaultMyComponentHelmet is a component used to add HTML tags inside the <head> tag of a page. Take the following example:
ℹ️
Helmetis a reexport of theHelmetcomponent from thereact-helmetlibrary.
importReactfrom'react'import{Helmet}from'vtex.render-runtime'functionMyComponent(){return(<><Helmet><metaproperty="og:type"content="article"/></Helmet></>)}exportdefaultMyComponentThe Link React component is responsible for rendering an a HTML element that, when clicked, navigates the user to the provided route.
ℹ️ Notice that the
Linkcomponent has a similar API to thenavigatemethod from theuseRuntimehook.
| Name | Type | Description | Default |
|---|---|---|---|
page | string | The name of the page that the user will be redirected to. Maps to a blocks.json block (e.g., 'store.product') | |
to | string | The URL of the page that the user will be redirected to (e.g., /shirt/p?skuId=1). Notice that to is an alternative to page and it contains the whole URL instead of the page name. | |
params | object | The param values of the page path in a key-value format (e.g, {slug: 'shirt'}). Params that starts with __ are not considered on path transformations, and can be generaly be used as an alternative to query params | {} |
query | string | The representation of the query params that are appended to the page path (e.g., skuId=231.) | '' |
onClick | function | A callback that is fired when the user clicks on a component (e.g., () => alert('Salut')) | |
replace | boolean | The boolean value used to indicate if it should call (true) the replace function to navigate or not (false) |
Other props you pass will be forwarded to the a component and can be used for customization.
Take the following usage examples:
importReactfrom'react'import{Link}from'vtex.render-runtime'functionMyComponent(){return<Linkto="/otherpage"classname="c-on-base">Hello</Link>}exportdefaultMyComponentimportReactfrom'react'import{Link}from'vtex.render-runtime'functionMyComponent(){constparams={slug: PRODUCT_SLUG,// Considered on path transformations (/{slug}/p)__listName: 'List of products'// Ignored on path transformations__yourProductPageParam: YOUR_PARAM// Ignored on path transformations}return<Linkto="/productpage"params={params}>Hello</Link>}exportdefaultMyComponent
⚠️ We always recommend using thecanUseDOMvariable when possible.
NoSSR is a React component that avoids rendering its children during Server-Side Rendering (SSR).
ℹ️ Notice that the
NoSSRcomponent is especially useful in cases the components use DOM related data (e.g:documentorwindow).
Take the following usage example:
importReactfrom'react'import{NoSSR}from'vtex.render-runtime'importDomRelatedComponentfrom'./DomRelatedComponent'functionMyComponent(){return(<NoSSRonSSR={<div>Loading...</div>}><DomRelatedComponent/></NoSSR>)}withRuntimeContext is a React High Order Component (HOC) that allows class components to access the runtime context.
ℹ️ When using function components, you can use
useRuntimeContexthook instead.
Take the following usage example:
importReactfrom'react'import{withRuntimeContext,RenderContext}from'vtex.render-runtime'classMyComponentextendsReact.Component<{runtime: RenderContext}>{render({ runtime }){return<div>This is the current page id: "{runtime.page}"</div>}}constMyComponentWithRuntime=withRuntimeContext(MyComponent)Notice that, when in SSR mode, you can optionally provide the onSSR prop together with a component to render instead.