Skip to content

Repository files navigation

Render Runtime

The Render Runtime app is responsible for handling runtime execution of React apps in the VTEX IO Platform. Additionally, it exports:

ℹ️ 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.

Variables

canUseDOM

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 canUseDOM variable is especially useful in cases the components use DOM related data (e.g: document or window).

Take the following usage example:

importReactfrom'react'import{canUseDOM}from'vtex.render-runtime'functionMyComponent(){constdata=canUseDOM
? window.localStorage.getItem('foo')
: ''return<div>Hello</div>}exportdefaultMyComponent

Hooks

useRuntime

The 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:

NameTypeDescription
accountstringThe VTEX account name, (e.g., storecomponents).
bindingobjectAn object containing the id and canonicalBaseAddress of the store binding.
cultureobjectAn object containing culture, currency and locale information.
deviceInfoobjectAn object specifying the user device type (phone, desktop, tablet, or unknown). This data varies when the user resizes the window.
getSettingsfunctionA function that, when called, returns the public settings of an app.
hintsobjectAn 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.
historyobjectA history object reexported from the history package. For further information, check this link.
navigatefunctionA function used in the client-side to define the navigation behaviour.
pagestringThe current page id (e.g., store.home).
pagesobjectObject containing all pages. The keys are the pages ids (e.g., store.home).
routeobjectObject containing data related to the current route, such as id, path, blockId and others.
productionbooleanPoints if the app is in a production workspace (true) or not (false).
queryobjectThe URL query string values in a key-value format (e.g., { "foo": "bar" }).
renderMajornumberThe major version of the Render Runtime app.
rootPathstringThe store root path (e.g., /ar). If not specified, its value is undefined.
setQueryfunctionA function that can be called to set query string params.
workspacestringThe current workspace name (e.g., master).

Usage examples

Check the following section for usage examples on how to use the internal runtime variables.

account

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ account }=useRuntime()return<div>Welcome to {account}</div>}exportdefaultMyComponent

binding

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ binding }=useRuntime()return<div>Canonical address is "{binding.canonicalBaseAddress}"</div>}exportdefaultMyComponent

Type:

interfaceBindingInfo{id: stringcanonicalBaseAddress: string}

Example value:

{
"id": "aacb06b3-a8fa-4bab-b5bd-2d654d20dcd8",
"canonicalBaseAddress": "storetheme.vtex.com/"
}

culture

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ culture }=useRuntime()return<div>Current active locale is: "{culture.locale}"</div>}exportdefaultMyComponent

Type:

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": "$"
}

deviceInfo

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ deviceInfo }=useRuntime()return<div>This page is being rendered on a "{deviceInfo.type}"</div>}exportdefaultMyComponent

Type:

interfaceDeviceInfo{isMobile: booleantype: 'phone'|'tablet'|'desktop'|'unknown'}

Example value:

{
"isMobile": false,
"type": "desktop"
}

getSettings

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>}exportdefaultMyComponent

hints

importReactfrom'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>}exportdefaultMyComponent

Type:

interfaceHints{desktop: booleanmobile: booleantablet: booleanphone: booleanunknown: boolean}

Example value:

{
"desktop": true,
"mobile": false,
"tablet": false,
"phone": false,
"unknown": false,
}

history

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ history }=useRuntime()consthandleClick=()=>{history.goBack()}return<buttononClick={handleClick}>Back</button>}exportdefaultMyComponent

navigate

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ navigate }=useRuntime()consthandleClick=()=>{navigate({to: '/other-page'})}return<buttononClick={handleClick}>Go</button>}exportdefaultMyComponent

Function param:

interfaceNavigateOptions{fallbackToWindowLocation?: booleanhash?: stringpage?: stringparams?: anyquery?: anyreplace?: booleanrootPath?: stringscrollOptions?: false|{baseElementId: string,behavior: 'auto'|'smooth'left: numbertop: number}skipSetPath?: booleanto?: string}

page

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ page }=useRuntime()return<div>This is the current page id: "{page}"</div>}exportdefaultMyComponent

pages

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ pages, page }=useRuntime()return<div>This is the current page declarer: "{pages[page].declarer}"</div>}exportdefaultMyComponent

Example value:

{
"allowConditions": true,
"context": null,
"declarer": "vtex.store@2.x",
"path": "/",
"routeId": "store.home",
"blockId": "vtex.store-theme@4.x:store.home",
"map": []
}

route

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ route }=useRuntime()return<div>This is the current route full path: "{route.path}"</div>}exportdefaultMyComponent

Example 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
}

production

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>}exportdefaultMyComponent

query

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ query }=useRuntime()return<div>The current query strings are {JSON.stringify(query)}</div>}exportdefaultMyComponent

renderMajor

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ renderMajor }=useRuntime()return<div>This page is rendered using vtex.render-runtime@{renderMajor}.x</div>}exportdefaultMyComponent

rootPath

importReactfrom'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>}exportdefaultMyComponent

setQuery

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ setQuery }=useRuntime()consthandleClick=()=>{setQuery({foo: 'bar'})}return<button>Set</button>}exportdefaultMyComponent

workspace

importReactfrom'react'import{useRuntime}from'vtex.render-runtime'functionMyComponent(){const{ workspace }=useRuntime()return<div>This is the {workspace} workspace</div>}exportdefaultMyComponent

Components

Block (alias ExtensionPoint)

Block is a React component used to create Store Framework blocks.

For implementation details, take the following example.

ℹ️ Notice that the Block component will always expect a specific block id.

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>)}exportdefaultMyComponent

Helmet

Helmet is a component used to add HTML tags inside the <head> tag of a page. Take the following example:

ℹ️ Helmet is a reexport of the Helmet component from the react-helmet library.

importReactfrom'react'import{Helmet}from'vtex.render-runtime'functionMyComponent(){return(<><Helmet><metaproperty="og:type"content="article"/></Helmet></>)}exportdefaultMyComponent

Link

The Link React component is responsible for rendering an a HTML element that, when clicked, navigates the user to the provided route.

ℹ️ Notice that the Link component has a similar API to the navigate method from the useRuntime hook.

NameTypeDescriptionDefault
pagestringThe name of the page that the user will be redirected to. Maps to a blocks.json block (e.g., 'store.product')
tostringThe 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.
paramsobjectThe 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{}
querystringThe representation of the query params that are appended to the page path (e.g., skuId=231.)''
onClickfunctionA callback that is fired when the user clicks on a component (e.g., () => alert('Salut'))
replacebooleanThe 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>}exportdefaultMyComponent
importReactfrom'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

NoSSR

⚠️ We always recommend using the canUseDOM variable when possible.

NoSSR is a React component that avoids rendering its children during Server-Side Rendering (SSR).

ℹ️ Notice that the NoSSR component is especially useful in cases the components use DOM related data (e.g: document or window).

Take the following usage example:

importReactfrom'react'import{NoSSR}from'vtex.render-runtime'importDomRelatedComponentfrom'./DomRelatedComponent'functionMyComponent(){return(<NoSSRonSSR={<div>Loading...</div>}><DomRelatedComponent/></NoSSR>)}

withRuntimeContext (High Order Component)

withRuntimeContext is a React High Order Component (HOC) that allows class components to access the runtime context.

ℹ️ When using function components, you can use useRuntimeContext hook 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.

About

The VTEX Render framework runtime

Topics

Resources

Stars

31 stars

Watchers

50 watching

Forks

Releases

Packages

Used by

Contributors

Languages