diff --git a/assets/js/dashboard/filters.js b/assets/js/dashboard/filters.js
index a7399a05a9..9e7e9ef15c 100644
--- a/assets/js/dashboard/filters.js
+++ b/assets/js/dashboard/filters.js
@@ -7,7 +7,7 @@ function filterText(key, value, query) {
if (key === "goal") {
return Completed goal {value}
}
- if (key === "meta") {
+ if (key === "props") {
const [metaKey, metaValue] = Object.entries(value)[0]
const eventName = query.filters["goal"] ? query.filters["goal"] : 'event'
return {eventName}.{metaKey} is {metaValue}
@@ -49,7 +49,7 @@ function filterText(key, value, query) {
function renderFilter(history, [key, value], query) {
function removeFilter() {
let newQuery = removeQueryParam(location.search, key)
- if (key === 'goal') { newQuery = removeQueryParam(newQuery, 'meta') }
+ if (key === 'goal') { newQuery = removeQueryParam(newQuery, 'props') }
history.push({search: newQuery})
}
diff --git a/assets/js/dashboard/query.js b/assets/js/dashboard/query.js
index bd8200ddcf..155f77e132 100644
--- a/assets/js/dashboard/query.js
+++ b/assets/js/dashboard/query.js
@@ -24,7 +24,7 @@ export function parseQuery(querystring, site) {
to: q.get('to') ? parseUTCDate(q.get('to')) : undefined,
filters: {
'goal': q.get('goal'),
- 'meta': JSON.parse(q.get('meta')),
+ 'props': JSON.parse(q.get('props')),
'source': q.get('source'),
'utm_medium': q.get('utm_medium'),
'utm_source': q.get('utm_source'),
diff --git a/assets/js/dashboard/stats/conversions/index.js b/assets/js/dashboard/stats/conversions/index.js
index 9d50c5aa4e..f131bafd61 100644
--- a/assets/js/dashboard/stats/conversions/index.js
+++ b/assets/js/dashboard/stats/conversions/index.js
@@ -3,7 +3,7 @@ import { Link } from 'react-router-dom'
import Bar from '../bar'
import MoreLink from '../more-link'
-import MetaBreakdown from './meta-breakdown'
+import PropBreakdown from './prop-breakdown'
import numberFormatter from '../../number-formatter'
import * as api from '../../api'
@@ -45,7 +45,7 @@ export default class Conversions extends React.Component {
}
renderGoal(goal) {
- const renderMeta = this.props.query.filters['goal'] == goal.name && goal.meta_keys
+ const renderProps = this.props.query.filters['goal'] == goal.name && goal.prop_names
return (
@@ -59,7 +59,7 @@ export default class Conversions extends React.Component {
{numberFormatter(goal.total_count)}
- { renderMeta &&
@@ -55,26 +55,26 @@ export default class MetaBreakdown extends React.Component {
)
}
- changeMetaKey(newKey) {
+ changePropKey(newKey) {
window.localStorage[this.storageKey] = newKey
- this.setState({metaKey: newKey, loading: true}, this.fetchMetaBreakdown)
+ this.setState({propKey: newKey, loading: true}, this.fetchPropBreakdown)
}
renderBody() {
if (this.state.loading) {
return
} else {
- return this.state.breakdown.map((metaValue) => this.renderMetadataValue(metaValue))
+ return this.state.breakdown.map((propValue) => this.renderPropValue(propValue))
}
}
renderPill(key) {
- const isActive = this.state.metaKey === key
+ const isActive = this.state.propKey === key
if (isActive) {
return
{key}
} else {
- return
{key}
+ return
{key}
}
}
@@ -84,7 +84,7 @@ export default class MetaBreakdown extends React.Component {
Breakdown by:
- { this.props.goal.meta_keys.map(this.renderPill.bind(this)) }
+ { this.props.goal.prop_names.map(this.renderPill.bind(this)) }
{ this.renderBody() }
diff --git a/lib/plausible/stats/clickhouse.ex b/lib/plausible/stats/clickhouse.ex
index f707de5a21..7aa8e3b277 100644
--- a/lib/plausible/stats/clickhouse.ex
+++ b/lib/plausible/stats/clickhouse.ex
@@ -597,7 +597,7 @@ defmodule Plausible.Stats.Clickhouse do
ClickhouseRepo.exists?(from e in "events", where: e.domain == ^site.domain)
end
- def all_seen_metadata_keys(site, %Query{filters: %{"meta" => meta}} = query) when is_map(meta) do
+ def all_props(site, %Query{filters: %{"props" => meta}} = query) when is_map(meta) do
[{key, val}] = meta |> Enum.into([])
if val == "(none)" do
@@ -614,7 +614,7 @@ defmodule Plausible.Stats.Clickhouse do
end
end
- def all_seen_metadata_keys(site, query) do
+ def all_props(site, query) do
ClickhouseRepo.all(
from e in base_query_w_sessions_bare(site, query),
inner_lateral_join: meta in fragment("meta as m"),
@@ -625,7 +625,7 @@ defmodule Plausible.Stats.Clickhouse do
end)
end
- def metadata_breakdown(site, %Query{filters: %{"meta" => meta}} = query, key) when is_map(meta) do
+ def property_breakdown(site, %Query{filters: %{"props" => meta}} = query, key) when is_map(meta) do
[{_key, val}] = meta |> Enum.into([])
if val == "(none)" do
@@ -653,7 +653,7 @@ defmodule Plausible.Stats.Clickhouse do
end
end
- def metadata_breakdown(site, query, key) do
+ def property_breakdown(site, query, key) do
none = ClickhouseRepo.all(
from e in base_query_w_sessions(site, query),
where: fragment("not has(meta.key, ?)", ^key),
@@ -858,8 +858,8 @@ defmodule Plausible.Stats.Clickhouse do
q
end
- if query.filters["meta"] do
- [{key, val}] = query.filters["meta"] |> Enum.into([])
+ if query.filters["props"] do
+ [{key, val}] = query.filters["props"] |> Enum.into([])
if val == "(none)" do
from(
@@ -1070,8 +1070,8 @@ defmodule Plausible.Stats.Clickhouse do
q
end
- q = if query.filters["meta"] do
- [{key, val}] = query.filters["meta"] |> Enum.into([])
+ q = if query.filters["props"] do
+ [{key, val}] = query.filters["props"] |> Enum.into([])
if val == "(none)" do
from(
diff --git a/lib/plausible_web/controllers/api/external_controller.ex b/lib/plausible_web/controllers/api/external_controller.ex
index 20762e5106..2d1e2be40b 100644
--- a/lib/plausible_web/controllers/api/external_controller.ex
+++ b/lib/plausible_web/controllers/api/external_controller.ex
@@ -117,7 +117,7 @@ defmodule PlausibleWeb.Api.ExternalController do
end
defp parse_meta(params) do
- raw_meta = params["m"] || params["meta"]
+ raw_meta = params["m"] || params["meta"] || params["p"] || params["props"]
if raw_meta do
Jason.decode!(raw_meta)
else
diff --git a/lib/plausible_web/controllers/api/stats_controller.ex b/lib/plausible_web/controllers/api/stats_controller.ex
index 14d48db17e..f19f1b91bd 100644
--- a/lib/plausible_web/controllers/api/stats_controller.ex
+++ b/lib/plausible_web/controllers/api/stats_controller.ex
@@ -36,7 +36,7 @@ defmodule PlausibleWeb.Api.StatsController do
end
defp fetch_top_stats(site, %Query{filters: %{"goal" => goal}} = query) when is_binary(goal) do
- total_filter = Map.merge(query.filters, %{"goal" => nil, "meta" => nil})
+ total_filter = Map.merge(query.filters, %{"goal" => nil, "props" => nil})
prev_query = Query.shift_back(query)
unique_visitors = Stats.unique_visitors(site, %{query | filters: total_filter})
prev_unique_visitors = Stats.unique_visitors(site, %{prev_query | filters: total_filter})
@@ -260,18 +260,18 @@ defmodule PlausibleWeb.Api.StatsController do
def conversions(conn, params) do
site = conn.assigns[:site]
query = Query.from(site.timezone, params)
- metadata_keys = Stats.all_seen_metadata_keys(site, query)
+ prop_names = Stats.all_props(site, query)
conversions = Stats.goal_conversions(site, query)
- |> Enum.map(fn goal -> Map.put(goal, :meta_keys, metadata_keys[goal[:name]]) end)
+ |> Enum.map(fn goal -> Map.put(goal, :prop_names, prop_names[goal[:name]]) end)
json(conn, conversions)
end
- def meta_breakdown(conn, params) do
+ def prop_breakdown(conn, params) do
site = conn.assigns[:site]
query = Query.from(site.timezone, params)
- json(conn, Stats.metadata_breakdown(site, query, params["meta_key"]))
+ json(conn, Stats.property_breakdown(site, query, params["prop_name"]))
end
def current_visitors(conn, _) do
diff --git a/lib/plausible_web/router.ex b/lib/plausible_web/router.ex
index 23569aa0f2..d59fb545eb 100644
--- a/lib/plausible_web/router.ex
+++ b/lib/plausible_web/router.ex
@@ -59,7 +59,7 @@ defmodule PlausibleWeb.Router do
get "/:domain/operating-systems", StatsController, :operating_systems
get "/:domain/screen-sizes", StatsController, :screen_sizes
get "/:domain/conversions", StatsController, :conversions
- get "/:domain/meta-breakdown/:meta_key", StatsController, :meta_breakdown
+ get "/:domain/property/:prop_name", StatsController, :prop_breakdown
end
scope "/api", PlausibleWeb do
diff --git a/priv/tracker/js/analytics.js b/priv/tracker/js/analytics.js
index e53ae0c111..f874ee003c 100644
--- a/priv/tracker/js/analytics.js
+++ b/priv/tracker/js/analytics.js
@@ -1 +1 @@
-!function(i,r){"use strict";var o=i.location,s=i.document,e=s.querySelector('[src*="'+r+'"]'),l=e&&e.getAttribute("data-domain"),t=!1;function n(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(o.hostname)||"file:"===o.protocol)return console.warn("Ignoring event on localhost");var n={};n.n=e,n.u=o.href,n.d=l,n.r=s.referrer||null,n.w=i.innerWidth,console.log(t),t&&t.meta&&(n.m=JSON.stringify(t.meta));var a=new XMLHttpRequest;a.open("POST",r+"/api/event",!0),a.setRequestHeader("Content-Type","text/plain"),a.send(JSON.stringify(n)),a.onreadystatechange=function(){4==a.readyState&&t&&t.callback&&t.callback()}}function a(){n("pageview")}try{var c,p=i.history;p.pushState&&(c=p.pushState,p.pushState=function(){c.apply(this,arguments),a()},i.addEventListener("popstate",a));var u=i.plausible&&i.plausible.q||[];i.plausible=n;for(var d=0;d
");
\ No newline at end of file
+!function(i,r){"use strict";var s=i.location,o=i.document,e=o.querySelector('[src*="'+r+'"]'),l=e&&e.getAttribute("data-domain"),t=!1;function n(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(s.hostname)||"file:"===s.protocol)return console.warn("Ignoring event on localhost");var n={};n.n=e,n.u=s.href,n.d=l,n.r=o.referrer||null,n.w=i.innerWidth,t&&t.meta&&(n.m=JSON.stringify(t.meta)),t&&t.props&&(n.p=JSON.stringify(t.props));var a=new XMLHttpRequest;a.open("POST",r+"/api/event",!0),a.setRequestHeader("Content-Type","text/plain"),a.send(JSON.stringify(n)),a.onreadystatechange=function(){4==a.readyState&&t&&t.callback&&t.callback()}}function a(){n("pageview")}try{var p,c=i.history;c.pushState&&(p=c.pushState,c.pushState=function(){p.apply(this,arguments),a()},i.addEventListener("popstate",a));var u=i.plausible&&i.plausible.q||[];i.plausible=n;for(var d=0;d");
\ No newline at end of file
diff --git a/priv/tracker/js/plausible.hash.js b/priv/tracker/js/plausible.hash.js
index d67c0818fa..a78921c2ef 100644
--- a/priv/tracker/js/plausible.hash.js
+++ b/priv/tracker/js/plausible.hash.js
@@ -1 +1 @@
-!function(i,r){"use strict";var s=i.location,o=i.document,e=o.querySelector('[src*="'+r+'"]'),l=e&&e.getAttribute("data-domain"),t=!1;function n(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(s.hostname)||"file:"===s.protocol)return console.warn("Ignoring event on localhost");var n={};n.n=e,n.u=s.href,n.d=l,n.r=o.referrer||null,n.w=i.innerWidth,console.log(t),t&&t.meta&&(n.m=JSON.stringify(t.meta)),n.h=1;var a=new XMLHttpRequest;a.open("POST",r+"/api/event",!0),a.setRequestHeader("Content-Type","text/plain"),a.send(JSON.stringify(n)),a.onreadystatechange=function(){4==a.readyState&&t&&t.callback&&t.callback()}}function a(){n("pageview")}try{var c,p=i.history;p.pushState&&(c=p.pushState,p.pushState=function(){c.apply(this,arguments),a()},i.addEventListener("popstate",a)),i.addEventListener("hashchange",a);var u=i.plausible&&i.plausible.q||[];i.plausible=n;for(var h=0;h");
\ No newline at end of file
+!function(i,r){"use strict";var s=i.location,o=i.document,e=o.querySelector('[src*="'+r+'"]'),l=e&&e.getAttribute("data-domain"),t=!1;function n(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(s.hostname)||"file:"===s.protocol)return console.warn("Ignoring event on localhost");var n={};n.n=e,n.u=s.href,n.d=l,n.r=o.referrer||null,n.w=i.innerWidth,t&&t.meta&&(n.m=JSON.stringify(t.meta)),t&&t.props&&(n.p=JSON.stringify(t.props)),n.h=1;var a=new XMLHttpRequest;a.open("POST",r+"/api/event",!0),a.setRequestHeader("Content-Type","text/plain"),a.send(JSON.stringify(n)),a.onreadystatechange=function(){4==a.readyState&&t&&t.callback&&t.callback()}}function a(){n("pageview")}try{var c,p=i.history;p.pushState&&(c=p.pushState,p.pushState=function(){c.apply(this,arguments),a()},i.addEventListener("popstate",a)),i.addEventListener("hashchange",a);var u=i.plausible&&i.plausible.q||[];i.plausible=n;for(var h=0;h");
\ No newline at end of file
diff --git a/priv/tracker/js/plausible.js b/priv/tracker/js/plausible.js
index e53ae0c111..f874ee003c 100644
--- a/priv/tracker/js/plausible.js
+++ b/priv/tracker/js/plausible.js
@@ -1 +1 @@
-!function(i,r){"use strict";var o=i.location,s=i.document,e=s.querySelector('[src*="'+r+'"]'),l=e&&e.getAttribute("data-domain"),t=!1;function n(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(o.hostname)||"file:"===o.protocol)return console.warn("Ignoring event on localhost");var n={};n.n=e,n.u=o.href,n.d=l,n.r=s.referrer||null,n.w=i.innerWidth,console.log(t),t&&t.meta&&(n.m=JSON.stringify(t.meta));var a=new XMLHttpRequest;a.open("POST",r+"/api/event",!0),a.setRequestHeader("Content-Type","text/plain"),a.send(JSON.stringify(n)),a.onreadystatechange=function(){4==a.readyState&&t&&t.callback&&t.callback()}}function a(){n("pageview")}try{var c,p=i.history;p.pushState&&(c=p.pushState,p.pushState=function(){c.apply(this,arguments),a()},i.addEventListener("popstate",a));var u=i.plausible&&i.plausible.q||[];i.plausible=n;for(var d=0;d");
\ No newline at end of file
+!function(i,r){"use strict";var s=i.location,o=i.document,e=o.querySelector('[src*="'+r+'"]'),l=e&&e.getAttribute("data-domain"),t=!1;function n(e,t){if(/^localhost$|^127(?:\.[0-9]+){0,2}\.[0-9]+$|^(?:0*\:)*?:?0*1$/.test(s.hostname)||"file:"===s.protocol)return console.warn("Ignoring event on localhost");var n={};n.n=e,n.u=s.href,n.d=l,n.r=o.referrer||null,n.w=i.innerWidth,t&&t.meta&&(n.m=JSON.stringify(t.meta)),t&&t.props&&(n.p=JSON.stringify(t.props));var a=new XMLHttpRequest;a.open("POST",r+"/api/event",!0),a.setRequestHeader("Content-Type","text/plain"),a.send(JSON.stringify(n)),a.onreadystatechange=function(){4==a.readyState&&t&&t.callback&&t.callback()}}function a(){n("pageview")}try{var p,c=i.history;c.pushState&&(p=c.pushState,c.pushState=function(){p.apply(this,arguments),a()},i.addEventListener("popstate",a));var u=i.plausible&&i.plausible.q||[];i.plausible=n;for(var d=0;d");
\ No newline at end of file
diff --git a/tracker/src/plausible.js b/tracker/src/plausible.js
index aa5265374f..fc2b7481ce 100644
--- a/tracker/src/plausible.js
+++ b/tracker/src/plausible.js
@@ -20,6 +20,9 @@
if (options && options.meta) {
payload.m = JSON.stringify(options.meta)
}
+ if (options && options.props) {
+ payload.p = JSON.stringify(options.props)
+ }
{{#if hashMode}}
payload.h = 1
{{/if}}