From 2e61c2020c62af40ec01f4d8a62e47231b8b9938 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Tue, 26 May 2026 07:32:23 +0200 Subject: [PATCH 01/10] Add toggle_display_name to Feature; rename Funnels to include user journeys --- lib/plausible/billing/feature.ex | 10 +++++++++- lib/plausible_web/components/site/toggle_live.ex | 4 ++-- test/plausible/billing/plan_benefits_test.exs | 6 +++--- .../controllers/api/stats_controller/funnels_test.exs | 2 +- 4 files changed, 15 insertions(+), 7 deletions(-) diff --git a/lib/plausible/billing/feature.ex b/lib/plausible/billing/feature.ex index 69554d638e6f..5c455b29228a 100644 --- a/lib/plausible/billing/feature.ex +++ b/lib/plausible/billing/feature.ex @@ -14,6 +14,9 @@ defmodule Plausible.Billing.Feature do * `:display_name` - human-readable display name of the feature + * `:toggle_display_name` - human-readable display name used in dashboard + toggle notifications. Defaults to `:display_name` if not set. + * `:toggle_field` - the field in the %Plausible.Site{} schema that toggles the feature. If `nil` or not set, toggle/2 silently returns `:ok` @@ -109,6 +112,10 @@ defmodule Plausible.Billing.Feature do @impl true def display_name, do: Keyword.get(unquote(opts), :display_name) + def toggle_display_name do + Keyword.get(unquote(opts), :toggle_display_name, display_name()) + end + @impl true def toggle_field, do: Keyword.get(unquote(opts), :toggle_field) @@ -162,7 +169,8 @@ defmodule Plausible.Billing.Feature.Funnels do @moduledoc false use Plausible.Billing.Feature, name: :funnels, - display_name: "Funnels", + display_name: "Funnels and user journeys", + toggle_display_name: "Funnels", toggle_field: :funnels_enabled end diff --git a/lib/plausible_web/components/site/toggle_live.ex b/lib/plausible_web/components/site/toggle_live.ex index c374fd84bc60..8262d5da42ae 100644 --- a/lib/plausible_web/components/site/toggle_live.ex +++ b/lib/plausible_web/components/site/toggle_live.ex @@ -73,9 +73,9 @@ defmodule PlausibleWeb.Components.Site.Feature.ToggleLive do message = if new_setting do - "#{feature_mod.display_name()} are now visible again on your dashboard" + "#{feature_mod.toggle_display_name()} are now visible again on your dashboard" else - "#{feature_mod.display_name()} are now hidden from your dashboard" + "#{feature_mod.toggle_display_name()} are now hidden from your dashboard" end send(self(), {:feature_toggled, message, updated_site}) diff --git a/test/plausible/billing/plan_benefits_test.exs b/test/plausible/billing/plan_benefits_test.exs index 94f7e683b505..917737ea02ac 100644 --- a/test/plausible/billing/plan_benefits_test.exs +++ b/test/plausible/billing/plan_benefits_test.exs @@ -80,7 +80,7 @@ defmodule Plausible.Billing.PlanBenefitsTest do "Stats API (600 requests per hour)", "Looker Studio Connector", "Ecommerce revenue attribution", - "Funnels", + "Funnels and user journeys", "Consolidated View" ] end @@ -97,7 +97,7 @@ defmodule Plausible.Billing.PlanBenefitsTest do "5 years of data retention", "Custom Properties", "Ecommerce revenue attribution", - "Funnels", + "Funnels and user journeys", "Stats API (600 requests per hour)", "Looker Studio Connector", "Shared Segments", @@ -121,7 +121,7 @@ defmodule Plausible.Billing.PlanBenefitsTest do ) == [ "Everything in Growth", "Ecommerce revenue attribution", - "Funnels", + "Funnels and user journeys", "Shared Segments", "Consolidated View" ] diff --git a/test/plausible_web/controllers/api/stats_controller/funnels_test.exs b/test/plausible_web/controllers/api/stats_controller/funnels_test.exs index aaa7a11f34db..7bdee7d07943 100644 --- a/test/plausible_web/controllers/api/stats_controller/funnels_test.exs +++ b/test/plausible_web/controllers/api/stats_controller/funnels_test.exs @@ -237,7 +237,7 @@ defmodule PlausibleWeb.Api.StatsController.FunnelsTest do assert %{ "error" => - "Funnels is part of the Plausible Business plan. To get access to this feature, please upgrade your account." + "Funnels and user journeys is part of the Plausible Business plan. To get access to this feature, please upgrade your account." } == resp end end From 7fe71f4cb4127b8ce494c7f91d039b753dff9604 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Tue, 26 May 2026 07:32:27 +0200 Subject: [PATCH 02/10] Gate exploration availability on Funnels billing feature --- lib/plausible/teams/billing.ex | 3 ++- lib/plausible_web/controllers/stats_controller.ex | 12 ------------ lib/plausible_web/templates/stats/stats.html.heex | 4 +++- 3 files changed, 5 insertions(+), 14 deletions(-) diff --git a/lib/plausible/teams/billing.ex b/lib/plausible/teams/billing.ex index da06e0eaa464..d2b4389b8050 100644 --- a/lib/plausible/teams/billing.ex +++ b/lib/plausible/teams/billing.ex @@ -674,7 +674,8 @@ defmodule Plausible.Teams.Billing do end def allowed_features_for(team) do - team = Teams.with_subscription(team) + team = + Teams.with_subscription(team) features = case Plans.get_subscription_plan(team.subscription) do diff --git a/lib/plausible_web/controllers/stats_controller.ex b/lib/plausible_web/controllers/stats_controller.ex index 50288350552a..a627ca3f2c6c 100644 --- a/lib/plausible_web/controllers/stats_controller.ex +++ b/lib/plausible_web/controllers/stats_controller.ex @@ -105,7 +105,6 @@ defmodule PlausibleWeb.StatsController do hide_footer?: if(ce?() || demo, do: false, else: site_role != :public), consolidated_view?: consolidated_view?, consolidated_view_available?: consolidated_view_available?, - exploration_available?: exploration_available?(current_user), exploration_journey_end_event: exploration_journey_end_event, exploration_max_journey_steps: exploration_max_journey_steps, team_identifier: team_identifier, @@ -536,7 +535,6 @@ defmodule PlausibleWeb.StatsController do # no shared links for consolidated views consolidated_view?: false, consolidated_view_available?: false, - exploration_available?: exploration_available?(current_user), exploration_journey_end_event: exploration_journey_end_event, exploration_max_journey_steps: exploration_max_journey_steps, team_identifier: team_identifier, @@ -545,16 +543,6 @@ defmodule PlausibleWeb.StatsController do end end - if Mix.env() != :e2e_test do - on_ee do - defp exploration_available?(user), do: Plausible.Auth.super_admin?(user) - else - defp exploration_available?(_user), do: false - end - else - defp exploration_available?(_user), do: true - end - defp get_fallback_site_role(conn), do: if(role = conn.assigns[:site_role], do: role, else: :public) diff --git a/lib/plausible_web/templates/stats/stats.html.heex b/lib/plausible_web/templates/stats/stats.html.heex index c29317e9d1c0..50ae77b79aee 100644 --- a/lib/plausible_web/templates/stats/stats.html.heex +++ b/lib/plausible_web/templates/stats/stats.html.heex @@ -47,7 +47,9 @@ data-segments={Jason.encode!(@segments)} data-is-consolidated-view={Jason.encode!(@consolidated_view?)} data-consolidated-view-available={Jason.encode!(@consolidated_view_available?)} - data-exploration-available={Jason.encode!(@exploration_available?)} + data-exploration-available={ + to_string(Plausible.Billing.Feature.Funnels.check_availability(@site.team) == :ok) + } data-exploration-journey-end-event={@exploration_journey_end_event} data-exploration-max-journey-steps={@exploration_max_journey_steps} data-team-identifier={@team_identifier} From 824e83e6d01ba11c48ab6f10831a304563e17738 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Tue, 26 May 2026 07:32:30 +0200 Subject: [PATCH 03/10] Remove exploration_wildcard_disabled feature flag --- lib/plausible_web/controllers/api/stats_controller.ex | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/lib/plausible_web/controllers/api/stats_controller.ex b/lib/plausible_web/controllers/api/stats_controller.ex index 5a03f31fbe4f..8bfc4aba2f44 100644 --- a/lib/plausible_web/controllers/api/stats_controller.ex +++ b/lib/plausible_web/controllers/api/stats_controller.ex @@ -140,7 +140,6 @@ defmodule PlausibleWeb.Api.StatsController do on_ee do alias Plausible.Stats.Exploration - @exploration_wildcard_disabled_flag :exploration_wildcard_disabled if Mix.env() == :e2e_test do @exploration_hourly_limit 100_000 @exploration_burst_limit 100_000 @@ -170,13 +169,10 @@ defmodule PlausibleWeb.Api.StatsController do {:ok, journey} <- parse_journey(steps), {:ok, direction} <- parse_exploration_direction(params["direction"]), query = Query.from(site, params, debug_metadata: debug_metadata(conn)), - include_wildcard? = - not FunWithFlags.enabled?(@exploration_wildcard_disabled_flag, for: site), {:ok, next_steps} <- Exploration.next_steps(site, query, journey, search_term: search_term, - direction: direction, - include_wildcard?: include_wildcard? + direction: direction ) do json(conn, next_steps) else @@ -221,13 +217,10 @@ defmodule PlausibleWeb.Api.StatsController do {:ok, journey} <- parse_journey(steps), {:ok, direction} <- parse_exploration_direction(params["direction"]), query = Query.from(site, params, debug_metadata: debug_metadata(conn)), - include_wildcard? = - not FunWithFlags.enabled?(@exploration_wildcard_disabled_flag, for: site), {:ok, next_steps} <- Exploration.next_steps(site, query, journey, search_term: search_term, direction: direction, - include_wildcard?: include_wildcard?, max_candidates: @exploration_max_candidates ), funnel <- maybe_include_funnel(include_funnel?, query, journey, direction) do From 720c97741dd94beb3a5ef71fea1926b880e912c8 Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Tue, 26 May 2026 07:32:34 +0200 Subject: [PATCH 04/10] Show upgrade notice for exploration when billing unavailable --- .../components/feature-setup-notice.tsx | 2 +- assets/js/dashboard/stats/behaviours/index.js | 39 +++++++++++++++---- .../stats/behaviours/modes-context.tsx | 2 +- 3 files changed, 33 insertions(+), 10 deletions(-) diff --git a/assets/js/dashboard/components/feature-setup-notice.tsx b/assets/js/dashboard/components/feature-setup-notice.tsx index 570b04a808c7..b5ebeb6373e7 100644 --- a/assets/js/dashboard/components/feature-setup-notice.tsx +++ b/assets/js/dashboard/components/feature-setup-notice.tsx @@ -85,7 +85,7 @@ export function FeatureSetupNotice({ {info}
- {renderHideButton()} + {typeof onHideAction === 'function' && renderHideButton()} {renderCallToAction()}
diff --git a/assets/js/dashboard/stats/behaviours/index.js b/assets/js/dashboard/stats/behaviours/index.js index 8ffca74f1624..f718787486b6 100644 --- a/assets/js/dashboard/stats/behaviours/index.js +++ b/assets/js/dashboard/stats/behaviours/index.js @@ -32,7 +32,7 @@ import { getSpecialGoal, isPageViewGoal, isSpecialGoal } from '../../util/goals' /*global BUILD_EXTRA*/ /*global require*/ -function maybeRequire() { +function maybeRequireFunnels() { if (BUILD_EXTRA) { // eslint-disable-next-line @typescript-eslint/no-require-imports return require('../../extra/funnel') @@ -46,12 +46,12 @@ function maybeRequireExploration() { // eslint-disable-next-line @typescript-eslint/no-require-imports return require('../../extra/exploration') } else { - return { FunnelExploration: null } + return { default: null } } } -const Funnel = maybeRequire().default -const { FunnelExploration } = maybeRequireExploration() +const Funnel = maybeRequireFunnels().default +const FunnelExploration = maybeRequireExploration().default function singleGoalFilterApplied(dashboardState) { const goalFilter = getGoalFilter(dashboardState) @@ -304,7 +304,24 @@ function Behaviours({ importedDataInView, setMode, mode }) { if (FunnelExploration === null) { return featureUnavailable() } - return + + if (site.explorationAvailable) { + return + } + + const callToAction = { action: 'Upgrade', link: '/billing/choose-plan' } + + return ( + + ) } function renderFunnels() { @@ -383,8 +400,14 @@ function Behaviours({ importedDataInView, setMode, mode }) { function featureUnavailable() { return ( -
- This feature is unavailable +
+ This report is available in Plausible Cloud + + Learn more +
) } @@ -537,7 +560,7 @@ function Behaviours({ importedDataInView, setMode, mode }) { Funnels ))} - {!site.isConsolidatedView && site.explorationAvailable && ( + {!site.isConsolidatedView && isEnabled(Mode.EXPLORATION) && ( Date: Tue, 26 May 2026 07:32:37 +0200 Subject: [PATCH 05/10] Update exploration availability tests to use billing --- .../controllers/stats_controller_test.exs | 42 ++++++++++++++----- 1 file changed, 32 insertions(+), 10 deletions(-) diff --git a/test/plausible_web/controllers/stats_controller_test.exs b/test/plausible_web/controllers/stats_controller_test.exs index 7d49250c951b..21758345d296 100644 --- a/test/plausible_web/controllers/stats_controller_test.exs +++ b/test/plausible_web/controllers/stats_controller_test.exs @@ -22,7 +22,7 @@ defmodule PlausibleWeb.StatsControllerTest do assert text_of_attr(resp, @react_container, "data-props-available") == "true" assert text_of_attr(resp, @react_container, "data-site-segments-available") == "true" assert text_of_attr(resp, @react_container, "data-funnels-available") == "true" - assert text_of_attr(resp, @react_container, "data-exploration-available") == "false" + assert text_of_attr(resp, @react_container, "data-exploration-available") == "true" assert text_of_attr(resp, @react_container, "data-has-props") == "false" assert text_of_attr(resp, @react_container, "data-logged-in") == "false" assert text_of_attr(resp, @react_container, "data-current-user-role") == "public" @@ -150,17 +150,39 @@ defmodule PlausibleWeb.StatsControllerTest do assert text_of_attr(resp, @react_container, "data-logged-in") == "true" end - test "non-superadmin can't see exploration funnel UI", %{conn: conn, site: site} do - populate_stats(site, [build(:pageview)]) - conn = get(conn, "/" <> site.domain) - resp = html_response(conn, 200) - assert text_of_attr(resp, @react_container, "data-exploration-available") == "false" - end - on_ee do - test "superadmin can see exploration funnel UI", %{conn: conn, site: site, user: user} do - patch_env(:super_admin_user_ids, [user.id]) + test "can't see exploration funnel UI if funnels feature unavailable", %{ + conn: conn, + site: site, + user: user + } do + subscribe_to_growth_plan(user) populate_stats(site, [build(:pageview)]) + conn = get(conn, "/" <> site.domain) + resp = html_response(conn, 200) + assert text_of_attr(resp, @react_container, "data-exploration-available") == "false" + end + + test "can see exploration funnel UI on trial", %{conn: conn, site: site} do + populate_stats(site, [build(:pageview)]) + conn = get(conn, "/" <> site.domain) + resp = html_response(conn, 200) + assert text_of_attr(resp, @react_container, "data-exploration-available") == "true" + end + + test "can see exploration funnel UI past trial with funnels feature enabled", %{ + conn: conn, + site: site, + user: user + } do + populate_stats(site, [build(:pageview)]) + + site.team + |> Plausible.Teams.Team.end_trial() + |> Plausible.Repo.update!() + + subscribe_to_enterprise_plan(user, features: [Plausible.Billing.Feature.Funnels]) + conn = get(conn, "/" <> site.domain) resp = html_response(conn, 200) assert text_of_attr(resp, @react_container, "data-exploration-available") == "true" From a259c48f247e12b2b432b9786ecce7127e9c7ee8 Mon Sep 17 00:00:00 2001 From: Sanne de Vries Date: Mon, 25 May 2026 17:05:46 +0200 Subject: [PATCH 06/10] Add preview mocks for the Exploration, Funnels and Properties reports - Preview mocks are non-interactive, blurred previews of the reports that are rendered behind the CTA when the feature isn't available on the current plan. They give users an at-a-glance idea of what the report looks like without needing to navigate elsewhere. Always heavily blurred in their parent container, so the goal is to be suggestive rather than pixel-perfect. --- .../components/feature-preview-mocks.tsx | 101 ++++++++++++++++++ .../components/feature-setup-notice.tsx | 95 +++++++++++----- assets/js/dashboard/components/icons.tsx | 17 +++ assets/js/dashboard/components/pill.tsx | 14 ++- assets/js/dashboard/stats/behaviours/index.js | 15 ++- 5 files changed, 215 insertions(+), 27 deletions(-) create mode 100644 assets/js/dashboard/components/feature-preview-mocks.tsx diff --git a/assets/js/dashboard/components/feature-preview-mocks.tsx b/assets/js/dashboard/components/feature-preview-mocks.tsx new file mode 100644 index 000000000000..93ea4c15cfd8 --- /dev/null +++ b/assets/js/dashboard/components/feature-preview-mocks.tsx @@ -0,0 +1,101 @@ +import React from 'react' +import classNames from 'classnames' + +/* + * Non-interactive previews of the Funnels / Properties / Exploration reports, + * rendered behind the CTA when the feature isn't available on the current + * plan. They give users an at-a-glance idea of what the report looks like + * without needing to navigate elsewhere. Always heavily blurred in their + * parent container, so the goal is to be suggestive rather than pixel-perfect. + */ + +export function PropertiesPreviewMock() { + const rows = [98, 82, 68, 60, 45, 21, 12, 8, 5, 2] + + return ( +
+ {rows.map((width, i) => ( +
+ ))} +
+ ) +} + +export function FunnelsPreviewMock() { + const steps = [{ visitors: 100 }, { visitors: 55 }, { visitors: 24 }] + + return ( +
+
+ +
+ {steps.map((step, i) => ( +
+
+
+
+ ))} +
+ +
+ {steps.map((_, i) => ( +
+
+
+ ))} +
+
+ ) +} + +export function ExplorationPreviewMock() { + const columns = [ + [98, 96, 54, 42, 27, 18, 15, 10, 5], + [88, 70, 68, 30, 18, 16, 10, 9, 5], + [82, 78, 48, 35, 25, 14, 12, 10, 5] + ] + + return ( +
+ {columns.map((rows, colIdx) => ( +
+
+
+
+
+ {rows.map((width, i) => ( +
+ ))} +
+
+ ))} +
+ ) +} diff --git a/assets/js/dashboard/components/feature-setup-notice.tsx b/assets/js/dashboard/components/feature-setup-notice.tsx index b5ebeb6373e7..3149989fb849 100644 --- a/assets/js/dashboard/components/feature-setup-notice.tsx +++ b/assets/js/dashboard/components/feature-setup-notice.tsx @@ -1,20 +1,37 @@ import React from 'react' +import classNames from 'classnames' import { MODES } from '../stats/behaviours/modes-context' import * as api from '../api' import { useSiteContext } from '../site-context' +import { Pill } from './pill' +import { DiamondIcon } from './icons' +import { buttonClassName } from './button' + +function BusinessPill() { + return ( + + + Business + + ) +} export function FeatureSetupNotice({ feature, title, info, callToAction, - onHideAction + secondaryCallToAction, + onHideAction, + previewMock }: { feature: keyof typeof MODES title: React.ReactNode info: React.ReactNode callToAction: { link: string; action: string } - onHideAction: () => void + secondaryCallToAction?: { link: string; action: string } + onHideAction: (() => void) | null + previewMock?: React.ReactNode }) { const site = useSiteContext() const sectionTitle = MODES[feature].title @@ -30,7 +47,7 @@ export function FeatureSetupNotice({ method: 'PUT', body: { feature: feature } }) - .then(() => onHideAction()) + .then(() => onHideAction?.()) .catch((error) => { if (!(error instanceof api.ApiError)) { throw error @@ -43,23 +60,12 @@ export function FeatureSetupNotice({ return ( -

{callToAction.action}

- - - + {callToAction.action} →
) } @@ -68,24 +74,65 @@ export function FeatureSetupNotice({ return ( ) } + function renderSecondaryCallToAction() { + if (!secondaryCallToAction) { + return null + } + return ( + + {secondaryCallToAction.action} + + ) + } + return ( -
-
+
+ {previewMock && ( + + )} +
+ {previewMock && ( +
+ +
+ )}
{title}
-
+
{info}
-
+
{typeof onHideAction === 'function' && renderHideButton()} + {renderSecondaryCallToAction()} {renderCallToAction()}
diff --git a/assets/js/dashboard/components/icons.tsx b/assets/js/dashboard/components/icons.tsx index 281f1f6a58ea..0439666850bc 100644 --- a/assets/js/dashboard/components/icons.tsx +++ b/assets/js/dashboard/components/icons.tsx @@ -133,6 +133,23 @@ export const FolderIcon = ({ className }: { className?: string }) => ( ) +export const DiamondIcon = ({ className }: { className?: string }) => ( + + + +) + export const Spinner = ({ className }: { className?: string }) => ( = { + green: 'bg-green-50 dark:bg-green-900/60 text-green-700 dark:text-green-300', + yellow: + 'bg-yellow-100 dark:bg-yellow-900/40 text-yellow-600 dark:text-yellow-400' +} + export type PillProps = { className?: string + color?: PillColor children: ReactNode } -export function Pill({ className, children }: PillProps) { +export function Pill({ className, color = 'green', children }: PillProps) { return (
diff --git a/assets/js/dashboard/stats/behaviours/index.js b/assets/js/dashboard/stats/behaviours/index.js index f718787486b6..e96326d7ecd8 100644 --- a/assets/js/dashboard/stats/behaviours/index.js +++ b/assets/js/dashboard/stats/behaviours/index.js @@ -3,6 +3,11 @@ import * as storage from '../../util/storage' import ImportedQueryUnsupportedWarning from '../imported-query-unsupported-warning' import Properties from './props' import { FeatureSetupNotice } from '../../components/feature-setup-notice' +import { + ExplorationPreviewMock, + FunnelsPreviewMock, + PropertiesPreviewMock +} from '../../components/feature-preview-mocks' import { hasConversionGoalFilter, getGoalFilter, @@ -316,10 +321,12 @@ function Behaviours({ importedDataInView, setMode, mode }) { feature={Mode.EXPLORATION} title={'Discover how visitors navigate your site'} info={ - 'See where visitors continue, convert or leave with detailed path exploration' + 'User journeys allow you to see how visitors navigate your site, where they convert and where they drop off.' } callToAction={callToAction} + secondaryCallToAction={{ action: 'Learn more', link: '#' }} onHideAction={null} + previewMock={} /> ) } @@ -350,6 +357,9 @@ function Behaviours({ importedDataInView, setMode, mode }) { } callToAction={callToAction} onHideAction={() => disableMode(Mode.FUNNELS)} + previewMock={ + !site.funnelsAvailable ? : undefined + } /> ) } else { @@ -383,6 +393,9 @@ function Behaviours({ importedDataInView, setMode, mode }) { } callToAction={callToAction} onHideAction={() => disableMode(Mode.PROPS)} + previewMock={ + !site.propsAvailable ? : undefined + } /> ) } else { From aa4709719830f9b0b71de76324a170acd2f28a37 Mon Sep 17 00:00:00 2001 From: Sanne de Vries Date: Mon, 25 May 2026 18:16:07 +0200 Subject: [PATCH 07/10] Update copy --- .../js/dashboard/components/feature-setup-notice.tsx | 2 +- assets/js/dashboard/stats/behaviours/index.js | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/assets/js/dashboard/components/feature-setup-notice.tsx b/assets/js/dashboard/components/feature-setup-notice.tsx index 3149989fb849..7fd9a349a8b4 100644 --- a/assets/js/dashboard/components/feature-setup-notice.tsx +++ b/assets/js/dashboard/components/feature-setup-notice.tsx @@ -116,7 +116,7 @@ export function FeatureSetupNotice({ className={classNames( 'relative py-3 max-w-2xl', previewMock && - 'max-w-[600px] md:p-8 md:bg-white md:dark:bg-gray-800 md:border md:border-gray-100 md:dark:border-gray-750 md:rounded-lg md:shadow-xl' + 'max-w-lg md:p-8 md:bg-white md:dark:bg-gray-800 md:border md:border-gray-100 md:dark:border-gray-750 md:rounded-lg md:shadow-xl' )} > {previewMock && ( diff --git a/assets/js/dashboard/stats/behaviours/index.js b/assets/js/dashboard/stats/behaviours/index.js index e96326d7ecd8..9af9181a6262 100644 --- a/assets/js/dashboard/stats/behaviours/index.js +++ b/assets/js/dashboard/stats/behaviours/index.js @@ -319,9 +319,9 @@ function Behaviours({ importedDataInView, setMode, mode }) { return ( disableMode(Mode.FUNNELS)} @@ -387,9 +387,9 @@ function Behaviours({ importedDataInView, setMode, mode }) { return ( disableMode(Mode.PROPS)} From fdd31bb1433cd8650b35383833addda291d06ff4 Mon Sep 17 00:00:00 2001 From: Sanne de Vries Date: Mon, 25 May 2026 19:31:02 +0200 Subject: [PATCH 08/10] Update link to user journeys docs --- assets/js/dashboard/stats/behaviours/index.js | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/assets/js/dashboard/stats/behaviours/index.js b/assets/js/dashboard/stats/behaviours/index.js index 9af9181a6262..c611b3bb35b7 100644 --- a/assets/js/dashboard/stats/behaviours/index.js +++ b/assets/js/dashboard/stats/behaviours/index.js @@ -324,7 +324,10 @@ function Behaviours({ importedDataInView, setMode, mode }) { 'See how visitors move between pages and events to understand browsing behavior.' } callToAction={callToAction} - secondaryCallToAction={{ action: 'Learn more', link: '#' }} + secondaryCallToAction={{ + action: 'Learn more', + link: 'https://plausible.io/docs/user-journeys' + }} onHideAction={null} previewMock={} /> @@ -389,7 +392,7 @@ function Behaviours({ importedDataInView, setMode, mode }) { feature={Mode.PROPS} title={'Attach your own data to the stats'} info={ - "Create custom metrics and analyze data specific to your business." + 'Create custom metrics and analyze data specific to your business.' } callToAction={callToAction} onHideAction={() => disableMode(Mode.PROPS)} From 58ebfbde4ac011101f2de83e149f29f0c5c648bd Mon Sep 17 00:00:00 2001 From: Sanne de Vries Date: Mon, 25 May 2026 19:43:53 +0200 Subject: [PATCH 09/10] Update border color of preview mocks --- assets/js/dashboard/components/feature-preview-mocks.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/assets/js/dashboard/components/feature-preview-mocks.tsx b/assets/js/dashboard/components/feature-preview-mocks.tsx index 93ea4c15cfd8..33460196284f 100644 --- a/assets/js/dashboard/components/feature-preview-mocks.tsx +++ b/assets/js/dashboard/components/feature-preview-mocks.tsx @@ -74,7 +74,7 @@ export function ExplorationPreviewMock() {
From d97ca3f5ec77ebe876a17d59bab0ebe657de428a Mon Sep 17 00:00:00 2001 From: Adam Rutkowski Date: Tue, 26 May 2026 10:42:08 +0200 Subject: [PATCH 10/10] unformat --- lib/plausible/teams/billing.ex | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/lib/plausible/teams/billing.ex b/lib/plausible/teams/billing.ex index d2b4389b8050..da06e0eaa464 100644 --- a/lib/plausible/teams/billing.ex +++ b/lib/plausible/teams/billing.ex @@ -674,8 +674,7 @@ defmodule Plausible.Teams.Billing do end def allowed_features_for(team) do - team = - Teams.with_subscription(team) + team = Teams.with_subscription(team) features = case Plans.get_subscription_plan(team.subscription) do