Changelog

Thumbnail image for changelog item

Getting started checklist

We updated our new user onboarding experience by creating a checklist. The checklist includes key steps needed to start using Dopt. We of course used Dopt to create the checklist with our own custom components ✨.

Billing page

The new billing page lets you see your plan, details about your MTU and flow usage, and the ability to upgrade plans. If you’re on a paid plan, you can access your invoices. You can access the billing page in Settings → Billing.

Billing page

We've also updated our Free plan experience to better display your usage in the main navigation.

Essential setup example

We released a new Dopt example: setup experiences. Setup experiences are useful for walking a user through crucial steps that might be necessary to get running in your product such as connecting to data sources or installing browser extensions. They are also helpful for gathering contextual information about a user to aid in building customized experiences in your app.

Check out the interactive setup example and code repo →

Other improvements

  • We’ve updated our Vue docs and in-app usage guides. In addition to the SDK’s README and technical typedocs, we’ve added a new in-depth guide that walks through how to use blocks, flows, and fields within your Vue app. We’ve also added pointers to each of our Vue composables, allowing you to directly and headlessly work with our Checklist, Tour, Modal, and Card components in your apps.

Thumbnail image for changelog item

Introducing the new Dopt Vue SDK

We’re super excited to release our Dopt Vue SDK, a new SDK that makes it easy to build better onboarding and education experiences in any Vue app.

Our Vue SDK offers a convenient way to access, update, and react to flows and blocks to build onboarding experiences. The SDK exposes a DoptPlugin which you can add to your Vue app. Once you’ve added the plugin, you can use our composables to bind Dopt state with your own UI.

The Vue SDK has full parity with our React and JavaScript SDKs, and our composables allow you to work headlessly with all of Dopt’s components like our Tours and Checklists.

It’s published to npm as @dopt/vue, and you can dig into our implementation by visiting Github (dopt/odopt).

See an example tour built with our Vue SDK →

Improved users pages

We enhanced the users pages to show the user’s email if the user has been identified with an email property. This should make it much easier to view and understand your users.

Dopt users page

If a user doesn’t have an email property, we’ll show their identifier instead.

Learn more about identifying users in Dopt →

Other improvements

  • We added framework-specific guides for Next.js, Remix, and more when working with our React components.
  • We made our JavaScript SDK a lot easier to work with. It’s now updated to support full reactivity for all flows, blocks, and components. You can access these instances at any time and always receive updates when they change. The SDK also supports use as a singleton in your application (i.e. creation at application start and subsequent reconfiguration when users, flows, etc., change). Under the hood, we use our improved JavaScript SDK to power our new Vue SDK. You can see a detailed changelog for 3.6.0.
  • You can now use the delete key in addition to backspace to delete things on the flow canvas.
  • We now keep your environment setting sticky across all pages.

Thumbnail image for changelog item

Carry over in-progress users beta

The new “Carry over in-progress users” transition enables you to seamlessly transition users and their state to a new flow version without having the user restart or exit the flow, so you can iterate on flows without users losing progress. For example, if you have 150 users on a checklist version who have completed different amounts of items, you could create a new checklist version with new items and transition the in-progress users to the new version. If a user's state can't be carried over due to incompatible changes like loops in the flow, those users will be restarted from the beginning of the flow. This feature is currently in beta — we’d love your feedback!

We also renamed the other transition methods and redesigned the transition modal to be much more clear.

Read the docs →

Enhancements to built-in analytics

We’ve upgraded our in-app analytics capabilities to better encapsulate funnel analysis. Only users who have started in the specified period will be counted towards the finished and stopped statistics.

Flow analytics page

We’ve also included percentage markers and trend indicators to show how many users out of the ones that started the flow have finished or stopped and if that number has increased or decreased since the previous period.

Improvements to how we build our open source packages

Our open source packages previously produced build artifacts that were intended to be friendly to various build and module systems by using "type": "commonjs" in their package.json (the default and less modern configuration) and by using file extensions to delineate between module systems (e.g. mjs for ESM and cjs for CJS). This strategy caused issues for older build tools that do not support these file extensions.

We’ve moved all of our open source packages and their transitive "dependencies" to use @dopt/pkg-build, our newly created CLI for building packages in the most backward compatible way we can come up with.

This strategy shifts us to:

  1. Use "type": "module" in our package.json
  2. Output files with .js extensions
  3. Produce a ./cjs directory in the build output that contains a thin package.json, which configures "type": "commonjs" explicitly, conceptually overriding the "type": "module" configuration of the actual package.json.

Improvements to component types

We now export the component hook return type definition to make it easier to type the custom components you build on top of our component hooks. Here’s an example of using them to define props in a custom checklist:

import { type ChecklistItem } from '@dopt/react-checklist/hooks';
interface CustomChecklistItemProps {  completed: ChecklistItem['completed'];  title: ChecklistItem['title'];  body: ChecklistItem['body'];}

Other improvements

  • Our new HTML rich text render enables you to use Dopt’s rich text fields in all non-React UIs you’re building. Read the docs →
  • You can no longer reset the flow state when the flow is disabled.

Thumbnail image for changelog item

Announcing in-app announcements

We’ve added support for making in-app announcements without code changes! First, use Dopt to develop an in-app modal, card, fly-out (or anything) and then launch announcements through it without a dev.

This enables you to announce new products or features, communicate changes, notify users, and promote events in your product.

To deploy self-serve in-app announcements, you use the new Restart all users version transition combined with the latest version tag in your code.

Read more at our blog here →

Read the guide on launching in-app announcements in our docs →

New in-app getting started tutorial

Our new getting started tutorial helps you learn the basics of Dopt by creating an example app that uses our new pre-built components and rich text content. The example flow is now created on demand rather than automatically, helping to keep your workspace tidy.

You can access the in-app getting started tutorial via the main nav.

See a live version of the example app you create in the tutorial →

Easier user and group identification in React

We shipped @dopt/react-users, a React-specific utility for identifying users and groups to Dopt. The goal was to make the identification of users and initialization of our React SDK dead simple. See a typical usage in our example code here.

The packages provides a DoptUsersProvider that you initialize with your User API key. Here’s an example:

<DoptUsersProvider apiKey={DOPT_USERS_API_KEY}>  <App /></DoptUsersProvider>

Inside the <App /> from above, you can now use the package’s hooks, identifyUser and identifyGroup. Here’s an example of identifyUser:

export function App() {  // Identify an example user to Dopt the first time the App loads.  const userId = useIdentifyUser({    identifier: nanoid(),    properties: {      company: 'Dopt',      role: 'admin',      inTrial: true,    },  });
  return (    <DoptProvider      apiKey={DOPT_BLOCKS_API_KEY}      userId={userId}      flowVersions={{ 'custom-card-component': 1 }}    >      <Home />    </DoptProvider>  );}

The hook will correctly return undefined for the userId until the request has been made successfully, which allows the <DoptProvider /> to initialize correctly!

We've been using this wrapper package all over the place in our own examples and internal tests and found it super useful, so excited to ship it for all of you.

Read the docs →

In-app feedback

You can now give us feedback from in the product! You can find the feedback form in the main nav. We look forward to hearing from you 😄.

Other improvements

  • We’ve defaulted path names to complete making it easier to create paths from custom blocks. You can still rename the path to whatever you want!
  • We now only allow one menu and popover to be opened at time, simplifying the UI.
  • We fixed a bug where we weren’t redirecting users to the page they were trying to access if they happened to be logged out. You’ll now be redirected to the right page.