diff --git a/assets/js/dashboard/filters.js b/assets/js/dashboard/filters.js
index a7399a05a9f09316243b39b8a58692668f70a703..9e7e9ef15c4c4ac3571e9f33c2e8d02c0e4dd8b9 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 <span className="inline-block max-w-sm truncate">Completed goal <b>{value}</b></span>
   }
-  if (key === "meta") {
+  if (key === "props") {
     const [metaKey, metaValue] = Object.entries(value)[0]
     const eventName = query.filters["goal"] ? query.filters["goal"] : 'event'
     return <span className="inline-block max-w-sm truncate">{eventName}.{metaKey} is <b>{metaValue}</b></span>
@@ -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 bd8200ddcf6bdd0882374d6d9625795604b08131..155f77e132072cd3361ce39f5716878c6b2ba85f 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 9d50c5aa4ea4f9030eb7a85582b218aad900ab5b..f131bafd61fb69d85e8fa162edad7e5b81ce0bac 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 (
       <div className="my-2 text-sm" key={goal.name}>
@@ -59,7 +59,7 @@ export default class Conversions extends React.Component {
             <span className="font-medium inline-block w-20 text-right">{numberFormatter(goal.total_count)}</span>
           </div>
         </div>
-        { renderMeta && <MetaBreakdown site={this.props.site} query={this.props.query} goal={goal} /> }
+        { renderProps && <PropBreakdown site={this.props.site} query={this.props.query} goal={goal} /> }
       </div>
     )
   }
diff --git a/assets/js/dashboard/stats/conversions/meta-breakdown.js b/assets/js/dashboard/stats/conversions/prop-breakdown.js
similarity index 68%
rename from assets/js/dashboard/stats/conversions/meta-breakdown.js
rename to assets/js/dashboard/stats/conversions/prop-breakdown.js
index 00f4b9c4299bc6d701c4c3154e6e66497f91fa56..bbfc8d7a154606b768cc493f5669ec5522f5c555 100644
--- a/assets/js/dashboard/stats/conversions/meta-breakdown.js
+++ b/assets/js/dashboard/stats/conversions/prop-breakdown.js
@@ -5,39 +5,39 @@ import Bar from '../bar'
 import numberFormatter from '../../number-formatter'
 import * as api from '../../api'
 
-export default class MetaBreakdown extends React.Component {
+export default class PropertyBreakdown extends React.Component {
   constructor(props) {
     super(props)
-    let metaKey = props.goal.meta_keys[0]
-    this.storageKey = 'goalMetaTab__' + props.site.domain + props.goal.name
+    let propKey = props.goal.prop_names[0]
+    this.storageKey = 'goalPropTab__' + props.site.domain + props.goal.name
     const storedKey = window.localStorage[this.storageKey]
-    if (props.goal.meta_keys.includes(storedKey)) {
-      metaKey = storedKey
+    if (props.goal.prop_names.includes(storedKey)) {
+      propKey = storedKey
     }
-    if (props.query.filters['meta']) {
-      metaKey = Object.keys(props.query.filters['meta'])[0]
+    if (props.query.filters['props']) {
+      propKey = Object.keys(props.query.filters['props'])[0]
     }
 
     this.state = {
       loading: true,
-      metaKey: metaKey
+      propKey: propKey
     }
   }
 
   componentDidMount() {
-    this.fetchMetaBreakdown()
+    this.fetchPropBreakdown()
   }
 
-  fetchMetaBreakdown() {
+  fetchPropBreakdown() {
     if (this.props.query.filters['goal']) {
-      api.get(`/api/stats/${encodeURIComponent(this.props.site.domain)}/meta-breakdown/${encodeURIComponent(this.state.metaKey)}`, this.props.query)
+      api.get(`/api/stats/${encodeURIComponent(this.props.site.domain)}/property/${encodeURIComponent(this.state.propKey)}`, this.props.query)
         .then((res) => this.setState({loading: false, breakdown: res}))
     }
   }
 
-  renderMetadataValue(value) {
+  renderPropValue(value) {
     const query = new URLSearchParams(window.location.search)
-    query.set('meta', JSON.stringify({[this.state.metaKey]: value.name}))
+    query.set('props', JSON.stringify({[this.state.propKey]: value.name}))
 
     return (
       <div className="flex items-center justify-between my-2" key={value.name}>
@@ -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 <div className="px-4 py-2"><div className="loading sm mx-auto"><div></div></div></div>
     } 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 <li key={key} className="inline-block h-5 text-indigo-700 font-bold border-b-2 border-indigo-700">{key}</li>
     } else {
-      return <li key={key} className="hover:text-indigo-700 cursor-pointer" onClick={this.changeMetaKey.bind(this, key)}>{key}</li>
+      return <li key={key} className="hover:text-indigo-700 cursor-pointer" onClick={this.changePropKey.bind(this, key)}>{key}</li>
     }
   }
 
@@ -84,7 +84,7 @@ export default class MetaBreakdown extends React.Component {
         <div className="flex items-center pb-1">
           <span className="text-xs font-bold text-gray-600">Breakdown by:</span>
           <ul className="flex font-medium text-xs text-gray-500 space-x-2 leading-5 pl-1">
-            { this.props.goal.meta_keys.map(this.renderPill.bind(this)) }
+            { this.props.goal.prop_names.map(this.renderPill.bind(this)) }
           </ul>
         </div>
         { this.renderBody() }
diff --git a/lib/plausible/stats/clickhouse.ex b/lib/plausible/stats/clickhouse.ex
index f707de5a21be31a5ff804bdba7fcbd1f544fcf92..7aa8e3b27736d6167ef365e8062ca8d93806a345 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 20762e51067e3e51c8d1877ca775c27dc585735a..2d1e2be40b69ea3663b0659c602e265004110b9a 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 14d48db17e95a5f4c0bed819903806bc4724fee4..f19f1b91bd494b7ec25f1901227e5f6259890674 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 23569aa0f231cec7d9b39bd3470fff3a9bf5d91c..d59fb545eb504c2b2f328f281178221944c50d8c 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 e53ae0c1116c512ac12b5eb7ceb8eb094d50d6e1..f874ee003cd6c418db54402e1a1c38334d666d13 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<u.length;d++)n.apply(this,u[d]);"prerender"===s.visibilityState?s.addEventListener("visibilitychange",function(){t||"visible"!==s.visibilityState||(t=!0,a())}):a()}catch(e){console.error(e),(new Image).src=r+"/api/error?message="+encodeURIComponent(e.message)}}(window,"<%= base_url %>");
\ 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<u.length;d++)n.apply(this,u[d]);"prerender"===o.visibilityState?o.addEventListener("visibilitychange",function(){t||"visible"!==o.visibilityState||(t=!0,a())}):a()}catch(e){console.error(e),(new Image).src=r+"/api/error?message="+encodeURIComponent(e.message)}}(window,"<%= base_url %>");
\ No newline at end of file
diff --git a/priv/tracker/js/plausible.hash.js b/priv/tracker/js/plausible.hash.js
index d67c0818fabb943d1db3df412b36dceb3f4ec3a6..a78921c2efa11b82e76123a668d5154c2313ca69 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<u.length;h++)n.apply(this,u[h]);"prerender"===o.visibilityState?o.addEventListener("visibilitychange",function(){t||"visible"!==o.visibilityState||(t=!0,a())}):a()}catch(e){console.error(e),(new Image).src=r+"/api/error?message="+encodeURIComponent(e.message)}}(window,"<%= base_url %>");
\ 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<u.length;h++)n.apply(this,u[h]);"prerender"===o.visibilityState?o.addEventListener("visibilitychange",function(){t||"visible"!==o.visibilityState||(t=!0,a())}):a()}catch(e){console.error(e),(new Image).src=r+"/api/error?message="+encodeURIComponent(e.message)}}(window,"<%= base_url %>");
\ No newline at end of file
diff --git a/priv/tracker/js/plausible.js b/priv/tracker/js/plausible.js
index e53ae0c1116c512ac12b5eb7ceb8eb094d50d6e1..f874ee003cd6c418db54402e1a1c38334d666d13 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<u.length;d++)n.apply(this,u[d]);"prerender"===s.visibilityState?s.addEventListener("visibilitychange",function(){t||"visible"!==s.visibilityState||(t=!0,a())}):a()}catch(e){console.error(e),(new Image).src=r+"/api/error?message="+encodeURIComponent(e.message)}}(window,"<%= base_url %>");
\ 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<u.length;d++)n.apply(this,u[d]);"prerender"===o.visibilityState?o.addEventListener("visibilitychange",function(){t||"visible"!==o.visibilityState||(t=!0,a())}):a()}catch(e){console.error(e),(new Image).src=r+"/api/error?message="+encodeURIComponent(e.message)}}(window,"<%= base_url %>");
\ No newline at end of file
diff --git a/tracker/src/plausible.js b/tracker/src/plausible.js
index aa5265374f37e958d13e5822301c0c2d13158193..fc2b7481ce2ab011aa1a8fef7504330f2315fa6a 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}}