create-kywi-app 0.6.0 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (2) hide show
  1. package/lib/templates.mjs +19 -2
  2. package/package.json +1 -1
package/lib/templates.mjs CHANGED
@@ -828,6 +828,10 @@ import {
828
828
  setAccessCookie,
829
829
  clearSessionCookies,
830
830
  } from '@kywi-software/core/host'
831
+ // Edge-safe leaf helper: builds the kywi_utm cookie value core's collectUtm reads
832
+ // back. Its own dependency-free entry (never the DB-backed audiences barrel), so
833
+ // it is importable from this edge middleware.
834
+ import { UTM_COOKIE, utmCookieValue } from '@kywi-software/core/audiences/utm-persistence'
831
835
 
832
836
  /**
833
837
  * Server-side auth enforcement + transparent session refresh for /admin and the
@@ -874,17 +878,30 @@ const VISITOR_MAX_AGE = 60 * 60 * 24 * 365 * 2 // 2 years
874
878
  * Public (non-admin, non-API) request: never auth-gated. Ensure a stable
875
879
  * \`kywi_visitor\` id — mint one on first visit — and forward it to the render as
876
880
  * \`x-kywi-visitor\` so the page sees it on this very request (the freshly set
877
- * cookie is not yet readable via cookies()). Everything else passes through.
881
+ * cookie is not yet readable via cookies()). Also forward the full request URL
882
+ * as \`x-kywi-url\` (query string included) so the server render can read UTM
883
+ * params off the very first request — without it, campaign personalization
884
+ * would never fire on the landing page. Everything else passes through.
878
885
  */
879
886
  function handlePublicRequest(req: NextRequest): NextResponse {
880
887
  const existing = req.cookies.get(VISITOR_COOKIE)?.value
881
888
  const visitorId = existing ?? crypto.randomUUID()
882
889
  const headers = new Headers(req.headers)
883
890
  headers.set('x-kywi-visitor', visitorId)
891
+ headers.set('x-kywi-url', req.nextUrl.href)
884
892
  const res = NextResponse.next({ request: { headers } })
885
893
  if (!existing) {
886
894
  res.cookies.set(VISITOR_COOKIE, visitorId, { path: '/', maxAge: VISITOR_MAX_AGE, sameSite: 'lax' })
887
895
  }
896
+ // Persist campaign UTM params so audience matching survives internal
897
+ // navigation: core's collectUtm reads this cookie when the URL has no utm_*
898
+ // query string. Only written when the request carries utm_* params, so an
899
+ // ordinary page view never clobbers a persisted campaign (utmCookieValue
900
+ // returns null → the existing cookie is left in place).
901
+ const utmValue = utmCookieValue(req.nextUrl.href)
902
+ if (utmValue) {
903
+ res.cookies.set(UTM_COOKIE, utmValue, { path: '/', maxAge: 60 * 60 * 24 * 30, sameSite: 'lax' })
904
+ }
888
905
  return res
889
906
  }
890
907
 
@@ -1594,7 +1611,7 @@ export function PersonalizationRuntime({ audiences, serverSignals, selfIdWidget
1594
1611
  currentPath,
1595
1612
  serverSignals,
1596
1613
  ...(selfIdWidget
1597
- ? { selfIdWidget: { ...selfIdWidget, audiences: audiences.map((a) => a.id), currentPath } }
1614
+ ? { selfIdWidget: { ...selfIdWidget, audiences, currentPath } }
1598
1615
  : {}),
1599
1616
  })
1600
1617
  .catch(() => {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-kywi-app",
3
- "version": "0.6.0",
3
+ "version": "0.6.2",
4
4
  "description": "Scaffold a new Kywi CMS project — npx create-kywi-app my-site",
5
5
  "type": "module",
6
6
  "homepage": "https://github.com/Kywi-Software/kywi-cms#readme",