PostHog / posthog

🦔 PostHog provides open-source product analytics, session recording, feature flagging and A/B testing that you can self-host.
https://posthog.com
Other
20.6k stars 1.23k forks source link

Follow up surveys UX #16018

Open annikaschmid opened 1 year ago

annikaschmid commented 1 year ago

Icon

Survey list page

Survey results page

Release conditions

Overview page, running survey

Survey creation page

Other

Future work

liyiy commented 1 year ago

Agree with everything! All on the todo list

I think this should be the exact same as on a feature flag at least for users in terms of styling (have a nice box, rather than the one liner we have right now)

What did you mean by this? What is "this" referring to?

corywatilo commented 1 year ago

I spent some time thinking through the new survey creation flow, what it could/should look like now, and how it can be extensible for future growth. So rather than starting with just designs, I started with the data structure for what a survey could look like.

First I'll cover the survey types I think we could use at launch (or a subset of these), then go over wires for the actual new survey creation flow.

Survey types

For the purposes of a near-term product launch, I went with four different templates because:

Four types of surveys

  1. Feedback form (what we have today)
  2. NPS/rating
  3. Emoji reaction
  4. Vote + feedback (a 2-step form)

These forms are limited to the fields we add to them, but you'll see how they could easily be user-modifiable in the future in the suggested json I'll provide for each.

Feedback form

Here's the json I whipped up to build it. (Note: Obviously use this as inspiration, not as an edict of exactly how to build it.)

{
  "type": "feedback",
  "title": "Share your thoughts",
  "description": "Optional form description",
  "confirmation": "Thanks! Your feedback has been sent.",
  "settings": [
    {
      "position": "right",
      "colors": [
        {
          "light": [
            {
              "primary": "rgba(0,0,0,1)",
              "background": "rgba(0,0,0,.1)",
              "border": "rgba(0,0,0,.25)",
              "buttonBg": "rgba(0,0,255,1)",
              "buttonText": "rgba(255,255,255,1)"
            },
            {
              "primary": "rgba(255,255,255,1)",
              "background": "rgba(255,255,255,.1)",
              "border": "rgba(255,255,255,.25)",
              "button": "rgba(0,0,255,1)",
              "buttonText": "rgba(255,255,255,1)"
            }
          ]
        }
      ]
    }
  ],
  "field": [
    {
      "type": "textarea",
      "label": "Feedback",
      "placeholder": "Start typing...",
      "limit": "280"
    },
    {
      "type": "submit",
      "label": "Submit"
    }
  ]
}

NPS/rating

We can combine NPS and any arbitrary number of ratings (ie: 1-5) in the same form by including some parameters for the rating field.

{
  "type": "rating",
  "title": "How satisfied are you with our product?",
  "description": "Optional form description",
  "confirmation": "Thanks for sharing!",
  "settings": [
    {
      "position": "center",
      "colors": [
        {
          "light": [
            {
              "primary": "rgba(0,0,0,1)",
              "background": "rgba(0,0,0,.1)",
              "border": "rgba(0,0,0,.25)",
              "accent": "rgba(0,0,255,1)"
            },
            {
              "primary": "rgba(255,255,255,1)",
              "background": "rgba(255,255,255,.1)",
              "border": "rgba(255,255,255,.25)",
              "accent": "rgba(0,0,255,1)"
            }
          ]
        }
      ]
    }
  ],
  "field": [
    {
      "type": "number",
      "scale": 10,
      "increment": 1
    }
  ]
}

You'll see in the field, we specify the scale and increment of numbers that show. (We don't have to expose this to a user - we could easily create an NPS form, which includes 10, and a generic rating form, which includes 5 - and largely use the same code to power it.)

Emoji reaction

{
  "type": "emoji",
  "title": "How do you feel about this page?",
  "description": "Optional form description",
  "confirmation": "Thanks for your feedback!",
  "settings": [
    {
      "position": "right",
      "colors": [
        {
          "light": [
            {
              "primary": "rgba(0,0,0,1)",
              "background": "rgba(0,0,0,.1)",
              "border": "rgba(0,0,0,.25)"
            },
            {
              "primary": "rgba(255,255,255,1)",
              "background": "rgba(255,255,255,.1)",
              "border": "rgba(255,255,255,.25)"
            }
          ]
        }
      ]
    }
  ],
  "field": [
    {
      "type": "emoji",
      "label": "😡"
    },
    {
      "type": "emoji",
      "label": "😑"
    },
    {
      "type": "emoji",
      "label": "😃"
    }
  ]
}

In the above, we'd have to specify the order (low to high) so we know which emoji refers to what, in the same way the scale (1-5, 1-10) would work the same way.

Vote + feedback

This is a multi-screen survey where you have to answer the first question to get to the second question.

This introduces the concept of pages that could (in the future) be re-ordered.

{
  "type": "voteFeedback",
  "title": "How do you feel about this page?",
  "description": "Optional form description",
  "confirmation": "Thanks! Your feedback has been sent.",
  "settings": [
    {
      "position": "right",
      "colors": [
        {
          "light": [
            {
              "primary": "rgba(0,0,0,1)",
              "background": "rgba(0,0,0,.1)",
              "border": "rgba(0,0,0,.25)",
              "buttonBg": "rgba(0,0,255,1)",
              "buttonText": "rgba(255,255,255,1)"
            },
            {
              "primary": "rgba(255,255,255,1)",
              "background": "rgba(255,255,255,.1)",
              "border": "rgba(255,255,255,.25)",
              "button": "rgba(0,0,255,1)",
              "buttonText": "rgba(255,255,255,1)"
            }
          ]
        }
      ]
    }
  ],
  "pages": [
    {
      "field": [
        {
          "type": "vote",
          "options": [
            {
              "value": false,
              "icon": "thumbsUp"
            },
            {
              "value": true,
              "icon": "thumbsDown"
            }
          ]
        }
      ]
    },
    {
      "field": [
        {
          "type": "textarea",
          "label": "Any additional feedback?",
          "placeholder": "Start typing...",
          "limit": "280"
        },
        {
          "type": "submit",
          "label": "Submit"
        }
      ]
    }
  ]
}

Setting up an array of pages gets us to a spot where a) we can easily build multi-page forms, and b) they can eventually be user-customizable.

New survey setup flow

Rather than do a multi-page UI (which would be cleaner), I kept everything on one page here, with a live preview of what the widget I've chosen looks like in the place it would appear.

It breaks the steps into:

  1. Form type
  2. Presentation
  3. Form fields
  4. Customization
  5. Targeting

image

Form type & Presentation

In the above wire, I went for a more visual approach here (showing previews of what you'd get). For a barebones MVP, we could simplify it by just doing standard form fields like seen below, though it really wouldn't take much to get it to the place outlined above, which is much more clear to a user.

image

Customization

We could probably simplify this (ie: define a text color, an accent color, and a background color) but ultimately I think having more customization available is better, especially for a developer product.

@smallbrownbike and I chatted about this and we'd be down to work together on building out the front end templates/widgets since we have some relevant experience here with theming, shadow DOM, CSS variables, etc. So if y'all only want to focus on the UI of building/editing/viewing results, we'd be happy to work on the part that gets embedded.

Targeting

This is the most updated portion of the existing MVP, as it moves feature flags in here, as well as makes it a little more explicit about how you can target (especially with labels).


The above would get us to a really solid v1. Up to you how much of this we build today, but I think this would put us in a good spot to make sure we're building for the future without overbuilding right now.

annikaschmid commented 1 year ago

Thanks Cory, this is great!

Here is some feedback from my side:

Survey types

+1 that this is a great set and structure to start with. I think Li is already working on some of those. I also really like the visual approach (as compared to the dropdown).

I have a recommendation for one more, which we already launched: We have a new survey type called 'link' aka the user interviewer, which is essentially customisable text, with a button that goes to a third-party link. Could you add this to your options? I saw some other tools have an option on the button to do this (see screenshot). Another idea from James was to show "user interview" as a "form type", so that we guide users more to use this to set up user interviews, which I think is a great idea.

Screenshot 2023-07-07 at 15 43 44

New survey setup flow

Customization

If you and Eli want to work on the site app / popup / modal styling options, that would be awesome. I think those have a lot of potential. I also think the default option we have right now could look a bit prettier. We also have the early access site app, which maybe once we have this done for surveys, we can replicate it for early access.

Targeting

I wonder if this area should look "bigger", because we have similar targeting on flags ("release conditions") and there it looks much more impressive 😅

Other

When a user selects API/Headless, would you want to show the implementation guide on the survey setup screen? Or do you think it's fine if we only show it when the survey is set up? Right now, we do the second, but I wonder if that leaves users confused about how to actually turn it on / make it work.

Another thing we will add soon is a "recontact period", which can be set on a global level for surveys. Sprig has this option where you can overwrite it on the survey itself. I don't think this is critical, but I think the global setting is important, so that users don't get spammed. Adding it here for inspiration and that we keep thinking about it :)

Screenshot 2023-07-07 at 16 05 50
liyiy commented 1 year ago

Thanks for the feedback Cory! I agree that it's important to make sure the survey popup types are functional (working on more basic types right now). I was wondering if you had any additional feedback about how the survey results + view pages look like currently and what are the best ways to summarize an "overview" of the survey created, for example.

Other points of response:

@smallbrownbike and I chatted about this and we'd be down to work together on building out the front end templates/widgets since we have some relevant experience here with theming, shadow DOM, CSS variables, etc. So if y'all only want to focus on the UI of building/editing/viewing results, we'd be happy to work on the part that gets embedded.

This sounds great. Surveys functionality for response collection and events capture are integrated along with the UI template on the plugin app currently so there's a bit of work to do in order to separate function from form, and would love to work together on this!

So rather than starting with just designs, I started with the data structure for what a survey could look like.

Sorry I didn't include this anywhere earlier, here's a bit of background on how the data model currently works for surveys:

Surveys:

  1. type: (popover, permanent button, etc)
  2. linked_flag: feature flag to be associated with the survey as part of feature success
  3. targeting_flag: how user properties are stored like feature flag filters
  4. conditions: This is where we store things like url/selector conditions, it's an open JSON field right now so we can continue to add conditions along the way. { url: 'posthog', selector: null, ... } Both targeting_flag and conditions let the user choose who/where to target the surveys to
  5. appearance: This is where we store background color, button color, text color, etc. Open JSON field right now so we can continue adding on. However we should be careful on how much optionality we allow as at some point it sense for the user to do it the headless API route instead.
  6. questions: Questions are stored like this: open text example: [{ type: 'open', question: 'what do you think?' }] multiple choice example: [{ type: 'multiple_choice', question: 'pick one of these', choices: ['choice 1', 'choice 2', ...] }] NPS/ratings example: [{ type: 'rating', rating_display: 'numbers', scale: 5, question: '' }]

Surveys that are created are then evaluated by the posthog-js library, where it determines which surveys to show the user, before it's sent to the feature-surveys plugin app. There, the actual survey UI is created based on the configuration of appearance and questions fields. And then whenever a user is shown a survey, dismisses it, or completes it, we send in the associated events to PostHog. Let me know if this makes it clearer how the system is currently structured~

corywatilo commented 1 year ago

I was wondering if you had any additional feedback about how the survey results + view pages look like currently and what are the best ways to summarize an "overview" of the survey created, for example.

Sorry I haven't had a chance to wire this up yet. I think in the short term, a few small changes would clean it up nicely.