Thumbnail image for changelog item

Content fields

Fields enable you to define content in Dopt and access it with our SDKs to power in-product copy and configuration. You can think of fields like a lightweight in-product CMS — paired with the rest of our platform’s powerful building blocks to define the user targeting, logic, and actions of your onboarding and education flows.

Fields are key-value pairs that you can define as part of a block in Dopt’s visual flow builder. You can specify the type of the field: text, boolean, and number. We’ll be releasing more field types in the future.

Here’s a flow to power a simple modal:

Step block with fields

These fields can then be accessed with Dopt’s SDKs to power your product experience.

import { useBlock } from '@dopt/react';import { Modal } from './modal';
export function Application() {  const [{ state, getField }, { complete }] = useBlock('$BLOCK_ID');  return (    <main>      { && (        <Modal>          <h1>{getField('title')}</h1>          <p>{getField('body')}</p>          <button onClick={complete}>{getField('button')}</button>        </Modal>      )}    </main>  );}

Read the full blog post →

Read the fields docs →

1.0 SDK

The 1.0 release represents a significant milestone in terms of stability and our confidence in the core solution. It includes:

  • A reorganization of the block and flow states we expose
  • Methods for accessing states and commands for changing states
  • A new representation of the block and flow entities that we return to you
  • Group block types

Here’s the updated useBlock hook type definition:

interface Block<T> {  readonly kind: 'block';  readonly type: T;  readonly uid: string;  readonly sid: string;  readonly version: number;  readonly state: {    active: boolean;    completed: boolean;  };}
interface BlockIntention {  complete: () => void;}
const useBlock: (uid: Block['uid']) => [block: Block, intent: BlockIntention];

We offer a useFlow hook as the primary mechanism for accessing and transitioning flows. Here’s the hooks type definition:

interface Flow<T> {  readonly kind: 'flow';  readonly type: T;  readonly uid: string;  readonly sid: string;  readonly version: number;  readonly state: {    started: boolean;    completed: boolean;    exited: boolean;  };  readonly blocks: Block[];}
interface FlowIntention {  complete: () => void;  reset: () => void;  start: () => void;  exit: () => void;}
const useFlow: (uid: Flow['sid']) => [flow: Flow, intent: FlowIntention];

The most powerful concept here is that the flow has references to its blocks — meaning that you can use this hook to access all state for a flow (its state and the state of its blocks) and get live updates as that state changes.

You might have noted in the type definitions above that the type property on the flow and block interfaces is generic — this is to support us building and exposing new block types.

Read the full blog post →

Read the SDK docs →

Blocks JS client

We released a blocks JavaScript client. The blocks client is simple, language specific client to interface with Dopt’s blocks API for both client-side and server-side integrations.

Read the Blocks JS client docs →

Other improvements and bug fixes

  • Flow states on the users page now updates automatically.
  • Added “when all complete” to group block to make the logic more clear on the canvas.
  • Updated flow panel so values are automatically saved.
  • Fixed a bug when flow listing page wouldn’t load with an archived flow. Archived flows now will not be removed from users page.

Thumbnail image for changelog item

User groups, demo, & examples

Introducing user groups

We’re excited to introduce user groups for Dopt. A group is usually a company or a workspace, but could also be an account, project, team, or any other user grouping that is relevant to your product.

B2B SaaS products are collaborative by default. Users collaborate on workflows and complete tasks together, usually within a company, workspace, or account. Groups enable you to target Dopt onboarding and education flows based on the properties of those groups, not just an individual user.

Groups enable use cases like:

  • If == "pro", show the Pro onboarding flow that highlights the unique value props in that plan.
  • If == false AND == "admin", then show those admin users a flow to help them set up the integration.
  • If < 3, then show a flow to help users create their first projects so the company can work towards activating.

You set the targeting rules in the Start block.

Flow with group defined in targeting rule

Groups also give you an overview of users and their activities within a company, helping you understand how they’re experiencing your flows.

Group details page

Users can belong to many groups, supporting products where a user can be in many workspaces (like Notion or Slack).

You can associate users to groups when identifying users. This also acts as an upsert for the groups and group properties — if the group doesn’t exist, it will get created with the set properties, if the group does exist, the group properties will get updated. Here’s an example:

curl \-XPOST \-H "Content-Type: application/json" \-H "x-api-key:$USERS_API_KEY" \-d '{      "identifier": "2a845972-4cde-4cb4-ba14-5cb2fc15ec4c",      "properties": {        "name": "Evelyn Reichert",        "email": "",      },      "groups": [        {          "identifier": "21ab4-8786ca4-78e63c-4525ca434",          "properties": {            "name": "Acme co",            "plan": "pro",            "integration_setup": false,            "num_projects": 3,          }        }      ]    }'

Read the user group docs →

Demo and examples

We released a 5 min getting started demo that covers the basics of building onboarding with Dopt, from using the flow builder to using our SDKs to develop the experience.

We also released two example onboarding experiences built with Dopt:

  • Learn-by-doing onboarding example: This example shows how to use Dopt to build onboarding for a Kanban app that helps users learn the product by simply using it.
  • Getting started checklist example: This example shows a checklist style onboarding experience that guides users through the three key actions to get value out of a simple analytics app.

Stay tuned, we have got more coming!

Other improvements & fixes

  • You can keep your flow listing page tidy by archiving flows. When a flow is archived, it’s removed from the flow listing page and its configuration, versions, and associated user states are also removed. Archive flow docs →
  • Moved our Typedoc docs for the React SDK to

Thumbnail image for changelog item

SDK updates

We introduced a useFlow hook and withFlow HOC in the React SDK. The flow.reset() function resets all properties of the blocks in the flow to false. The .reset() function enables you to build experiences like “Restart walkthrough” at the end of an interactive walkthrough or “Reset onboarding help” for a user in their settings or admin panel. We’ll continue to release more flow level functions, like the ability to exit a flow and get all blocks in a flow.

Here’s an example of using the useFlow hook.

import { useFlow } from '@dopt/react';import { Modal } from '@your-company/modal';
export function Application() {  const [flow, intent] = useFlow('new-user-onboarding', 1);  return (    <main>      <Modal>        <h1>👏 Your onboarding has finished!</h1>        <p>Want to reset? click the button below.</p>        <button onClick={intent.reset}>Reset onboarding</button>      </Modal>    </main>  );}

useFlow SDK docs →

We’ve released the first version of the JavaScript blocks SDK. Unlike our React SDK, this SDK is framework agnostic. Users of Svelte, Vue.js, Angular, etc. we see you and are building to support you. The JavaScript SDK, like the React SDK, allows for subscription to block updates and exposes block intent methods for manipulating block state and transitioning flows.

Thinking about building onboarding in a JS runtime that doesn’t use React? Check this SDK out!

JS blocks SDK readme →

Our blocks SDK is now much more responsive when progressing state because we optimistically progress the state rather than waiting for a backend response. This is an optional boolean property that can be set in the Dopt provider. The default is true.

DoptProvider docs →

Other improvements & fixes

  • Blocks now update faster
  • The flow page now loads and updates faster
  • Fixed a bug where flow status didn’t update across environments
  • Fixed a bug where targeting rules were sometimes incorrectly disabled
  • The settings back button now brings you back your previous page rather than the home screen

Thumbnail image for changelog item

Settings and Blocks React SDK 0.2.0

Settings and members listing pages

We released a new settings page that helps you administer Dopt.

Members listing page displays all the people in your company that have a Dopt account, helping with security and auditing.

Account page displays your account details: currently name and email.

Environments page is the same page accessed through the environments picker that displays your environments and enables you to create and view API keys, now also accessible through settings.

You can access settings through the main nav in the bottom left.

Blocks React SDK 0.2.0

We released @dopt/react:0.2.0. Here's what's new:

We renamed useDopt and withDopt to useBlock and withBlock to make it more clear the SDK is working with blocks. This also makes it possible for us to introduce flow level SDK concepts. This change is backward-compatible. The old methods are still in the SDK and have been marked as deprecated.

We introduced a socket connection in the React SDK to the Blocks API. /identify calls to the Users API now propagate state changes based on updated user properties in real-time to the client. For example, if a user property changes (e.g. current_plan: free to current_plan: pro) results in the user meeting a flow's targeting rules, then the user will qualify for the flow and the updated state will be pushed to the client in real-time. This change is backward compatible and doesn't change the SDK's interface.

There's now an optional logLevel property in the DoptProvider that configures severity-based logging for the React SDK. This accepts the values: 'trace', 'debug', 'info', 'warn', 'error', 'silent' (default). Here's an example usage:

<DoptProvider  flowVersions={{ "user-onboarding": 2, "upsell-flow": 4 }}  userId={userId}  apiKey={blocksAPIKey}  logLevel=`warn`>  <Application /></DoptProvider>

Other improvements & fixes

  • Flows now default to being disabled in production environment when created.
  • Added a Using the React SDK guide in our docs that walk you through the tools that the React SDK provides and examples on how to use them to build an onboarding experience.
  • Added images that more clearly explain flows, blocks, and environments in docs.
  • Improved the Blocks React SDK readme & Users JS client readme.
  • Improved redirection logic so when you log in you’ll land on the same page you were on.