Server-side Rendering
Method One: Page-by-page useEffect
If you already have a successful and confirmed installation of Sovrn Commerce JavaScript (viglink-javascript)
<script
src="//cdn.viglink.com/api/vglnk.js"
async
type="text/javascript"
></script>you can call window.__commercejs.fetchProductRecommendations() when your page has rendered in the UI/fully hydrated.
// page.tsx
'use client'
import { useEffect } from 'react'
export default function MyPage() {
useEffect(() => {
window.__commercejs.fetchProductRecommendations()
}, [])
return (
<main>
<h1>My Page</h1>
</main>
)
}or with JavaScript:
// page.js
'use client'
import { useEffect } from 'react'
export default function MyPage() {
useEffect(() => {
window.__commercejs.fetchProductRecommendations()
}, [])
return (
<main>
<h1>My Page</h1>
</main>
)
}Method Two: Automatic on Route Change
This solution is designed for these specific dependency versions:
{
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0",
"next": "15.3.1"
}
}If you don't want to manually add the useEffect example shown above to every page, follow
these steps to automatically fetch products when the app route path changes.
TypeScript
Add a type definition for the commerce-js API in a global.d.ts file:
// global.d.ts
interface Window {
__commercejs: {
fetchProductRecommendations: () => void
}
}Create a file called sovrn-commerce.tsx. Here we'll define two components, SovrnCommerce and SovrnCommerceShoppingGallery.
First add SovrnCommerce. This component is responsible for loading the Sovrn JavaScript and
fetching product recommendations when the app path changes. If we do not detect a Sovrn Commerce shopping gallery, the function exits safely.
// sovrn-commerce.tsx
'use client'
import { usePathname } from 'next/navigation'
import { useEffect, useRef } from 'react'
export function SovrnCommerce() {
const pathname = usePathname()
const pathnameRef = useRef(pathname)
useEffect(() => {
if (pathnameRef.current !== pathname) {
pathnameRef.current = pathname
// if the app path changes, check to see if a shopping gallery is present in the DOM
// and fetch products for that page.
window.__commercejs.fetchProductRecommendations()
}
}, [pathname])
return (
<>
<script
dangerouslySetInnerHTML={{
__html: `
var vglnk = { key: '<your_api_key>' };
`,
}}
></script>
<script
src="//cdn.viglink.com/api/vglnk.js"
async
type="text/javascript"
></script>
</>
)
}Now add the SovrnCommerceShoppingGallery.
// sovrn-commerce.tsx
/**
* @see [documentation](#) for configuration options
*/
export function SovrnCommerceShoppingGallery() {
return <div className="sovrn-commerce-ai-shopping-gallery"></div>
}Add SovrnCommerce to the app root or root layout or some root level component that doesn't
unmount when route path changes.
// layout.tsx
export default function RootLayout({
children,
}: Readonly<{
children: React.ReactNode
}>) {
return (
<html lang="en">
<body>
{children}
<SovrnCommerce />
</body>
</html>
)
}Finally, add a shopping gallery to your page:
// page.tsx
export default function MyPage() {
return (
<main>
<h1>My Page</h1>
<SovrnCommerceShoppingGallery />
</main>
)
}JavaScript
These steps are nearly identical. Follow the TypeScript Instructions
but skip the global.d.ts type definition step and use .js file extensions: sovrn-commerce.js.
// sovrn-commerce.js
'use client'
import { usePathname } from 'next/navigation'
import { useEffect, useRef } from 'react'
export function SovrnCommerce() {
const pathname = usePathname()
const pathnameRef = useRef(pathname)
useEffect(() => {
if (pathnameRef.current !== pathname) {
pathnameRef.current = pathname
window.__commercejs.fetchProductRecommendations()
}
}, [pathname])
return (
<>
<script
dangerouslySetInnerHTML={{
__html: `
var vglnk = { key: '<your_api_key>' };
`,
}}
></script>
<script
src="//cdn.viglink.com/api/vglnk.js"
async
type="text/javascript"
></script>
</>
)
}
export function SovrnCommerceShoppingGallery() {
return <div className="sovrn-commerce-ai-shopping-gallery"></div>
}Updated 21 days ago
