SDKs
Server Side Rendering

Server Side rendering

This module aims to be used by frameworks relying on Server Side Rendering at runtime such as Nextjs, Remix, Sveltekit, QwikCity etc.

It's agnostic from the framework and can be used in any of them. Also, this module works at the edge and can be coupled with Vercel Edge Middleware for example (opens in a new tab).

Installation

$ npm install --save @progressively/server-side

Usage

This is an example using Nextjs (opens in a new tab) but you can find how to use it in your own framework in the example folder of the Github repository (opens in a new tab).

Default SSR usage

import { ProgressivelyProvider, useFlags } from "@progressively/react";
import { Progressively } from "@progressively/server-side";
 
// React Specific Section
const FlaggedComponent = () => {
  const { flags } = useFlags();
  /* ... */
};
 
const YourPage = ({ progressivelyProps }) => {
  return (
    <ProgressivelyProvider {...progressivelyProps}>
      <FlaggedComponent />
    </ProgressivelyProvider>
  );
};
// End of React Specific Section
 
export async function getServerSideProps({
  req,
  res,
}: {
  req: Request,
  res: any,
}) {
  // Agnostic cross-framework SSR call
  const sdk = Progressively.init("valid-sdk-key", {
    websocketUrl: "ws://localhost:4000", // only necessary when self hosting
    apiUrl: "http://localhost:4000", // only necessary when self hosting
    fields: {
      id: userIdFromNextjsCookie,
    },
  });
 
  const { data, response } = await sdk.loadFlags();
 
  return {
    props: {
      progressivelyProps: data,
    },
  };
}

SSR with sticky user

When using Progressively with a rollout percentage that is not 100%, you want your users to have a consistent experience. In order to do so, Progressively needs a way to stick a variant to a user id.

The handling of creating IDs for anonymous users is done by Progressively under the hood. However, we need an extra step on your side to make it work properly: you have to set a cookie and forward the cookie to the Progressively instance:

import { ProgressivelyProvider, useFlags } from "@progressively/react";
import { Progressively } from "@progressively/server-side";
 
const FlaggedComponent = () => {
  const { flags } = useFlags();
  /* ... */
};
 
const YourPage = ({ progressivelyProps }) => {
  return (
    <ProgressivelyProvider {...progressivelyProps}>
      <FlaggedComponent />
    </ProgressivelyProvider>
  );
};
 
export async function getServerSideProps({
  req,
  res,
}: {
  req: Request;
  res: any;
}) {
  const userIdFromNextjsCookie =
    (req as any).cookies?.["progressively-id"] || null;
 
  const sdk = Progressively.init("valid-sdk-key", {
      websocketUrl: "ws://localhost:4000",
      apiUrl: "http://localhost:4000",
      fields: {
        id: userIdFromNextjsCookie,
      },
    });
 
  const { data, response } = await sdk.loadFlags();
 
  const progressivelyCookie = response?.headers?.get("set-cookie");
  res.setHeader("set-cookie", progressivelyCookie);
 
  return {
    props: {
      progressivelyProps: data,
    },
  };
}