v1.2.0
v1.2.0
Highlights
- Visitor contexts now preserve the first landing URL, external referrer, and UTM campaign parameters that brought the visitor to the application.
- The first successful Stripe or Paddle product or subscription purchase now sets
converted_aton the user's contexts. - Admin user pages now show first-party lifecycle, acquisition, and conversion tracking, and the users list can display and sort by conversion date.
- Stripe plan switching works again with Dahlia flexible billing and
pending_if_incompleteupdates. - Markdown emails now embed a PNG application logo instead of relying on an inline SVG.
Added
Acquisition and conversion attribution
- Added
utm_source,utm_medium,utm_campaign,utm_term,utm_content,landing_url, andreferrercolumns to thecontextstable. The source and campaign columns are indexed. - Added first-touch attribution recording to the web and API context middleware. The first landing's acquisition record is preserved instead of being overwritten or combined with data from a later visit; internal referrers are ignored, URLs are limited to 2,000 characters, and UTM values are limited to 255 characters.
- The public
POST /api/contextendpoint can now receive an optionalurlandreferrerin its JSON body, allowing an approved first-party website to attach its own landing page and acquisition source to the shared visitor context. Malformed or oversized URLs are discarded. - Successful Stripe Checkout sessions and Paddle transactions now record their checkout or billing timestamp as the context's first
converted_atvalue for both configured products and subscriptions. Later purchases do not overwrite the original conversion time or update context activity. - Added feature coverage for first-touch attribution, cross-site attribution, invalid attribution input, product and subscription conversions through both payment providers, admin tracking details, and conversion-date sorting.
Admin analytics
- Added an analytics and tracking section to each admin user page. It shows the context ID, registration method, first and last activity, registration and conversion dates, UTM source, medium, campaign, term and content, landing page, and external referrer. The existing Umami session lookup remains available in the same section when Umami is configured.
- Added a sortable
Customer sincecolumn to the admin users list, backed by the context'sconverted_atvalue. Contexts without a recorded conversion display an empty value.
Changed
Billing
PaddleCheckoutButtonnow emits asuccessevent with the configured success URL when Paddle reportscheckout.completed.- The account billing page now closes the subscription dialogs after a successful plan switch, cancellation, or inline Paddle checkout.
Fixed
- Fixed Stripe plan changes failing after the Dahlia upgrade. Pending subscription updates no longer send
cancel_atorcancel_at_period_end, which Stripe does not support withpayment_behavior=pending_if_incomplete; cancellation cleanup remains in the dedicated resume flow. - Fixed Stripe subscription lifecycle webhooks returning
500errors because the custom Cashier customer model inferred a nonexistentstripe_user_idcolumn. Subscription creation, updates, and cancellations now use the existinguser_idforeign key and remain synchronized locally. - Fixed subscription dialogs remaining open after successful billing actions.
- Fixed application logos being missing or inconsistently rendered in Markdown emails by replacing the inline SVG with
public/inertia-start-logo.pngand embedding it as an inline PNG attachment. The shared Markdown mail and notification templates now pass the underlying mail message through to the logo component.
Removed
- Fresh installations no longer create the unused
lifetime_valueandcumulative_spendcontext columns, and the corresponding model casts and frontend type fields were removed. Existing databases keep these harmless columns unless an application removes them separately.
Dependencies
- Composer and npm dependency lockfiles were updated.
Upgrade Guide
- Run
composer install. - Run
npm install. - Run
php artisan migrateto add the attribution columns tocontexts. - Rebuild frontend assets with
npm run buildor your normal frontend workflow. - If another first-party website calls
POST /api/context, send its current absolute URL asurland, when available, the previous page asreferrerto record acquisition data. Existing calls that only sendX-Guestcontinue to work. - If you customized the Markdown mail templates or logo component, merge the updated
mailMessageprop forwarding and addpublic/inertia-start-logo.pngso the logo can be embedded in outgoing messages.