@usequark/quark-create-app 1.27.1 → 1.27.3
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.
- package/package.json +1 -1
- package/templates/base-project/apps/web/.env.example +20 -2
- package/templates/base-project/apps/web/next.config.js +10 -5
- package/templates/base-project/apps/web/src/app/_components/UmamiReplayRecorder.js +3 -3
- package/templates/base-project/apps/web/src/app/_components/UmamiWebVitals.js +2 -2
- package/templates/base-project/apps/web/src/app/layout.js +11 -15
- package/templates/base-project/apps/web/src/app/s/api/[endpoint]/route.js +328 -0
- package/templates/base-project/apps/web/src/app/s/script.js/route.js +128 -0
- package/templates/base-project/apps/web/src/lib/analytics/umami-before-send.js +7 -2
- package/templates/base-project/apps/web/src/lib/analytics/umami-config.js +101 -11
- package/templates/base-project/apps/web/src/lib/analytics/umami-csp.js +2 -1
- package/templates/base-project/apps/web/src/lib/analytics/umami-replay.js +172 -28
- package/templates/base-project/apps/web/src/lib/analytics/umami-web-vitals.js +30 -13
- package/templates/base-project/apps/web/src/lib/analytics/umami.js +7 -4
- package/templates/base-project/apps/web/src/lib/proxy-auth.js +63 -0
- package/templates/base-project/apps/web/src/proxy.js +10 -38
- package/templates/config/src/validate-env.js +25 -6
|
@@ -101,6 +101,10 @@ const ENV_DESCRIPTIONS = {
|
|
|
101
101
|
APP_URL: "Canonical application URL - derives NEXTAUTH_URL and CORS origins",
|
|
102
102
|
NEXT_PUBLIC_UMAMI_URL:
|
|
103
103
|
"Public Umami base URL for script.js and replay uploads",
|
|
104
|
+
UMAMI_UPSTREAM_URL:
|
|
105
|
+
"Server-only Umami base URL for the first-party proxy (rewrites + /s/api/* destination). Takes precedence over NEXT_PUBLIC_UMAMI_URL and keeps the analytics host out of the client bundle",
|
|
106
|
+
UMAMI_URL:
|
|
107
|
+
"Server-only Umami base URL alias for the first-party proxy (same as UMAMI_UPSTREAM_URL)",
|
|
104
108
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID: "Public Umami website UUID",
|
|
105
109
|
NEXT_PUBLIC_UMAMI_REPLAY_ENABLED:
|
|
106
110
|
"Enable local rrweb session replay uploads to Umami",
|
|
@@ -246,6 +250,10 @@ function createEnvSchema(service) {
|
|
|
246
250
|
NEXT_PUBLIC_UMAMI_URL: absoluteHttpUrl(
|
|
247
251
|
"NEXT_PUBLIC_UMAMI_URL must be an absolute http(s) URL",
|
|
248
252
|
),
|
|
253
|
+
UMAMI_UPSTREAM_URL: absoluteHttpUrl(
|
|
254
|
+
"UMAMI_UPSTREAM_URL must be an absolute http(s) URL",
|
|
255
|
+
),
|
|
256
|
+
UMAMI_URL: absoluteHttpUrl("UMAMI_URL must be an absolute http(s) URL"),
|
|
249
257
|
NEXT_PUBLIC_UMAMI_WEBSITE_ID: z
|
|
250
258
|
.string()
|
|
251
259
|
.refine((value) => isUuid(value), {
|
|
@@ -370,8 +378,13 @@ function createEnvSchema(service) {
|
|
|
370
378
|
}
|
|
371
379
|
}
|
|
372
380
|
|
|
373
|
-
// Umami replay requires full analytics contract
|
|
374
|
-
|
|
381
|
+
// Umami replay requires full analytics contract. A server-only
|
|
382
|
+
// upstream (UMAMI_UPSTREAM_URL / UMAMI_URL) counts as URL-present:
|
|
383
|
+
// the proxy rewrite/handler destination follows it.
|
|
384
|
+
const umamiUrl =
|
|
385
|
+
data.UMAMI_UPSTREAM_URL?.trim() ||
|
|
386
|
+
data.UMAMI_URL?.trim() ||
|
|
387
|
+
data.NEXT_PUBLIC_UMAMI_URL?.trim();
|
|
375
388
|
const umamiWebsiteId = data.NEXT_PUBLIC_UMAMI_WEBSITE_ID?.trim();
|
|
376
389
|
const umamiReplayEnabled = data.NEXT_PUBLIC_UMAMI_REPLAY_ENABLED?.trim();
|
|
377
390
|
const hasUmamiUrl = Boolean(umamiUrl);
|
|
@@ -385,7 +398,7 @@ function createEnvSchema(service) {
|
|
|
385
398
|
ctx.addIssue({
|
|
386
399
|
code: "custom",
|
|
387
400
|
message:
|
|
388
|
-
"NEXT_PUBLIC_UMAMI_REPLAY_ENABLED requires NEXT_PUBLIC_UMAMI_URL and NEXT_PUBLIC_UMAMI_WEBSITE_ID.",
|
|
401
|
+
"NEXT_PUBLIC_UMAMI_REPLAY_ENABLED requires an Umami URL (UMAMI_UPSTREAM_URL, UMAMI_URL, or NEXT_PUBLIC_UMAMI_URL) and NEXT_PUBLIC_UMAMI_WEBSITE_ID.",
|
|
389
402
|
});
|
|
390
403
|
}
|
|
391
404
|
});
|
|
@@ -455,14 +468,20 @@ function collectWarnings() {
|
|
|
455
468
|
}
|
|
456
469
|
}
|
|
457
470
|
|
|
458
|
-
// Umami pair completeness
|
|
459
|
-
|
|
471
|
+
// Umami pair completeness. Server-only upstream vars count as
|
|
472
|
+
// URL-present, matching the proxy destination preference.
|
|
473
|
+
const umamiUrl = (
|
|
474
|
+
process.env.UMAMI_UPSTREAM_URL ||
|
|
475
|
+
process.env.UMAMI_URL ||
|
|
476
|
+
process.env.NEXT_PUBLIC_UMAMI_URL ||
|
|
477
|
+
""
|
|
478
|
+
).trim();
|
|
460
479
|
const umamiWebsiteId = process.env.NEXT_PUBLIC_UMAMI_WEBSITE_ID?.trim();
|
|
461
480
|
const hasUmamiUrl = Boolean(umamiUrl);
|
|
462
481
|
const hasUmamiWebsiteId = Boolean(umamiWebsiteId);
|
|
463
482
|
if (hasUmamiUrl !== hasUmamiWebsiteId) {
|
|
464
483
|
warnings.push(
|
|
465
|
-
"Umami analytics is incomplete: set
|
|
484
|
+
"Umami analytics is incomplete: set an Umami URL (UMAMI_UPSTREAM_URL, UMAMI_URL, or NEXT_PUBLIC_UMAMI_URL) and NEXT_PUBLIC_UMAMI_WEBSITE_ID to enable tracking.",
|
|
466
485
|
);
|
|
467
486
|
}
|
|
468
487
|
|