Knowledge Base Article

Embed Sisense Linux in Next.js: SSR-safe script loading & client components [Linux]

Next.js is one of the most common frameworks in the React community for developers who need features like SSR and SEO, helping to avoid some of React's limitations. But if you've already tried to implement Sisense in Next.js, you've probably run into some errors. Don't worry that errors are common. Why does this happen?

Step-by-Step Guide:

Some Concepts First:

  • SSR (Server Side Rendering): On regular React (Vite, CRA, etc.), everything runs in the browser, so window, document, and global scripts are always available. In Next.js, your components may run on the server before they can access the browser or DOM objects.
  • Scripting: Since Next.js renders applications differently, there's a proper order to import scripts.
  • Client Components: By default, in Next.js (App Router,) all components are server components.

So in practice, what needs to change? 

ComposeSDK

For those who want to use Next.js with CSDK might not be possible at all. The Compose SDK was built for working using client-side aspects of React, like mutable URL path, also using Hooks and ContextAPI

You can follow the guide about setup in other frameworks, like Angular and Vue.

Instance Scripts:

The first step is loading the script. Next.js provides its own Script component, which you can import from next/script. The main difference is that this Script tag can work with SSR and lets you define a loading strategy.

import Script from "next/script";

export default function Page() {
  return (
    <>
      <Script
        src="<https://your-sisense-domain.com/js/sisense.js>"
        strategy="beforeInteractive" 
      />
      <div id="sisense-container" />
    </>
  );
}

Using the beforeInteractive strategy ensures the script always loads before your code runs.

Global Variable Access

If you're using EmbedSDK or Sisense.js, you will need access to the DOM, global variables, or even Sisense objects. Like I said above, these variables you can only access on the client side, so to handle this, follow these methods:

  • Add 'use client' at the top of your component (this does not work in the main root layout, why). This makes the component a client component, so you can use regular React hooks inside it.

Always interact with DOM objects inside React hooks like useEffect. This guarantees your code only runs in the client context.

'use client'
import { useEffect } from "react";

export default function SisenseJS() {
  useEffect(() => {
    if (typeof window !== "undefined" && window.Sisense) {
      window.Sisense.connect("<https://your-sisense-domain>", false)
        .then(app => console.log("Connected:", app))
        .catch(console.error);
    }
  }, []);

  return <div id="sisenseApp" />;
}

By adding 'use client' and these validations inside useEffect, you ensure that the window and the Sisense script are correctly loaded.

**Important: For Sisense.js and EmbedSDK, it's impossible to use them in server components because they require DOM properties. If you need an SSR, use the Iframe option.

CSP

A Content Security Policy (CSP) can sometimes block embedding through an iframe. To avoid this, make sure you add the right config in your next.config.js, for example:

import type { NextConfig } from 'next';

const nextConfig: NextConfig = {
  async headers() {
    return [
      {
        source: '/(.*)',
        headers: [
          {
            key: 'Content-Security-Policy',
            value:
              'frame-src <https://your-sisense-domain>; src <https://your-sisense-domain>',
          },
        ],
      },
    ];
  },
};

export default nextConfig;

This ensures that scripts and iframes from Sisense are allowed in your application.

Troubleshoots with Typescript

With you are using Next.js, probably it's with typescript, but window is not a fully typed object in Next.js when you inject some scripts in it, so to avoid that, you can extend the Window type in a .d.ts file, and add it to the typescript configuration:

// global.d.ts
export {};

declare global {
  interface Window {
    Sisense: any; 
    sisenseEmbed: any;
  }
}

You can get an example of the Embed SDK example using react, to create the interfaces, or follow the reference about Sisense.Js API.

Conclusion

When using Next.js, be aware of the differences between server-side and client-side. All Sisense embedding methods depend on DOM access (client-side), since Sisense is ultimately a web platform. Another useful resource is Next.js’s documentation on SSR and client components. Also, you can find an example of each kind of implementation attached here.

References/Related Content 

Disclaimer: This post outlines a potential custom workaround for a specific use case or provides instructions regarding a specific task. The solution may not work in all scenarios or Sisense versions, so we strongly recommend testing it in your environment before deployment. If you need further assistance with this, please let us know.

Updated 10-06-2025
No CommentsBe the first to comment