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 about 10 hours ago