@marvalt/digivalt-core 0.2.32 → 0.2.34
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/CHANGELOG.md +16 -0
- package/README.md +2 -1
- package/bin/init.cjs +46 -3
- package/docs/AI-MASTER-PROMPT.md +1 -0
- package/docs/README.md +3 -2
- package/docs/SEO-AIO.md +59 -0
- package/docs/SEO-PERFORMANCE.md +2 -0
- package/package.json +1 -1
- package/template/DIGIVALT_SETUP.md +4 -0
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,22 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.2.34] - 2026-09-22
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
- `digivalt-init` reports the app's dependency lockfile in preflight, warns when `.gitignore` excludes `package-lock.json`, and gives a manual action when no supported lockfile exists.
|
|
12
|
+
- Cloudflare Pages setup and AI scaffold guidance now require committing the package-manager lockfile so deployments install the tested dependency tree.
|
|
13
|
+
- Init smoke coverage for missing and ignored lockfiles.
|
|
14
|
+
|
|
15
|
+
**Publish/deploy:** publish **`@marvalt/digivalt-core@0.2.34`**. Consumer apps should upgrade and rerun `npx digivalt-init`; no WordPress plugin publish is required.
|
|
16
|
+
|
|
17
|
+
## [0.2.33] - 2026-09-19
|
|
18
|
+
|
|
19
|
+
### Added
|
|
20
|
+
- **`docs/SEO-AIO.md`** — developer/AI playbook for DigiValt SEO plugin + env + prerender. Linked from `docs/README.md` and `SEO-PERFORMANCE.md`.
|
|
21
|
+
|
|
22
|
+
**Publish/deploy:** publish **`@marvalt/digivalt-core@0.2.33`**. No required app code change; upgrade when you want the packaged handbook.
|
|
23
|
+
|
|
8
24
|
## [0.2.32] - 2026-09-18
|
|
9
25
|
|
|
10
26
|
### Added
|
package/README.md
CHANGED
|
@@ -30,7 +30,7 @@ The root package export remains as a thin compatibility layer for generator-focu
|
|
|
30
30
|
|
|
31
31
|
- **Subpath:** `import { DigiValtRouteSeo, DigiValtSeoHead, JsonLd, buildPageJsonLd, ... } from '@marvalt/digivalt-core/seo'`
|
|
32
32
|
- **Peer dependency:** `react-helmet-async` (v2+). Wrap the app in **`HelmetProvider`**.
|
|
33
|
-
- **Env:** **`VITE_SEO_*`** site identity
|
|
33
|
+
- **Env:** **`VITE_SEO_*`** site identity. Per-URL fields come from WordPress **`digivalt_seo`**. Playbook: **[docs/SEO-AIO.md](./docs/SEO-AIO.md)**. Env table / PageSpeed: **[docs/SEO-PERFORMANCE.md](./docs/SEO-PERFORMANCE.md)**.
|
|
34
34
|
- **Config:** `getSEOConfig()` / `getPerformanceConfig()` in `@marvalt/digivalt-core/config` read the same `VITE_*` values.
|
|
35
35
|
|
|
36
36
|
## Init Workflow
|
|
@@ -51,6 +51,7 @@ What init now does:
|
|
|
51
51
|
- refreshes `scripts/generate.ts` when it matches an older DigiVAlt-managed version
|
|
52
52
|
- warns instead of overwriting custom build logic or custom generator scripts
|
|
53
53
|
- warns when a local `wpRegistry.tsx` / `createAppRegistry` is present; use the published `/registry` helpers when practical
|
|
54
|
+
- reports a missing dependency lockfile or a `package-lock.json` excluded by `.gitignore`; commit the lockfile before Cloudflare Pages deployment
|
|
54
55
|
- reports stale legacy workarounds such as alias-link scripts and old root package generator imports
|
|
55
56
|
|
|
56
57
|
When to rerun it:
|
package/bin/init.cjs
CHANGED
|
@@ -51,6 +51,15 @@ const LEGACY_BUILD_MARKERS = [
|
|
|
51
51
|
'@marvalt/digivalt-core',
|
|
52
52
|
];
|
|
53
53
|
|
|
54
|
+
const LOCKFILE_NAMES = [
|
|
55
|
+
'package-lock.json',
|
|
56
|
+
'npm-shrinkwrap.json',
|
|
57
|
+
'pnpm-lock.yaml',
|
|
58
|
+
'yarn.lock',
|
|
59
|
+
'bun.lock',
|
|
60
|
+
'bun.lockb',
|
|
61
|
+
];
|
|
62
|
+
|
|
54
63
|
function getArgValue(flag) {
|
|
55
64
|
const index = args.indexOf(flag);
|
|
56
65
|
return index >= 0 ? args[index + 1] : undefined;
|
|
@@ -223,6 +232,24 @@ function findLocalRegistryFiles(srcDir) {
|
|
|
223
232
|
return matches;
|
|
224
233
|
}
|
|
225
234
|
|
|
235
|
+
function packageLockIsIgnored() {
|
|
236
|
+
const gitignore = readTextIfExists(path.join(targetDir, '.gitignore'));
|
|
237
|
+
if (!gitignore) return false;
|
|
238
|
+
|
|
239
|
+
let ignored = false;
|
|
240
|
+
for (const rawLine of gitignore.split(/\r?\n/)) {
|
|
241
|
+
const line = rawLine.trim();
|
|
242
|
+
if (!line || line.startsWith('#')) continue;
|
|
243
|
+
|
|
244
|
+
const negated = line.startsWith('!');
|
|
245
|
+
const pattern = (negated ? line.slice(1) : line).replace(/^\//, '');
|
|
246
|
+
if (pattern === 'package-lock.json') {
|
|
247
|
+
ignored = !negated;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
return ignored;
|
|
251
|
+
}
|
|
252
|
+
|
|
226
253
|
function inspectTargetApp(targetPackageJsonPath, templateGenerateScript) {
|
|
227
254
|
const packageJson = readJson(targetPackageJsonPath);
|
|
228
255
|
const scripts = packageJson.scripts || {};
|
|
@@ -295,6 +322,8 @@ function inspectTargetApp(targetPackageJsonPath, templateGenerateScript) {
|
|
|
295
322
|
legacyRootImport: Boolean(generateScriptContent && generateScriptContent.includes("import { generators } from '@marvalt/digivalt-core';")),
|
|
296
323
|
legacyViteConfigs,
|
|
297
324
|
localRegistryFiles: findLocalRegistryFiles(path.join(targetDir, 'src')),
|
|
325
|
+
lockfiles: LOCKFILE_NAMES.filter((name) => fs.existsSync(path.join(targetDir, name))),
|
|
326
|
+
packageLockIgnored: packageLockIsIgnored(),
|
|
298
327
|
};
|
|
299
328
|
}
|
|
300
329
|
|
|
@@ -305,6 +334,7 @@ function printPreflight(status) {
|
|
|
305
334
|
console.log(`- scripts.build: ${status.buildState}`);
|
|
306
335
|
console.log(`- scripts.build:dev: ${status.buildDevState}`);
|
|
307
336
|
console.log(`- scripts/generate.ts: ${status.generateState}`);
|
|
337
|
+
console.log(`- dependency lockfile: ${status.lockfiles.length > 0 ? status.lockfiles.join(', ') : 'missing'}`);
|
|
308
338
|
|
|
309
339
|
if (status.legacyHackFiles.length > 0 || status.legacyPostinstall || status.legacyRootImport || status.legacyViteConfigs.length > 0) {
|
|
310
340
|
console.log('- legacy DigiVAlt wiring detected: yes');
|
|
@@ -477,6 +507,18 @@ function collectLegacyWarnings(status) {
|
|
|
477
507
|
`Local WordPress registry detected (${status.localRegistryFiles.join(', ')}). Prefer \`@marvalt/digivalt-core/registry\`; existing files were not overwritten.`
|
|
478
508
|
);
|
|
479
509
|
}
|
|
510
|
+
|
|
511
|
+
if (status.packageLockIgnored) {
|
|
512
|
+
report.warnings.push(
|
|
513
|
+
'`package-lock.json` is ignored by `.gitignore`. Remove that rule and commit the lockfile so Cloudflare Pages installs the tested dependency tree.'
|
|
514
|
+
);
|
|
515
|
+
}
|
|
516
|
+
|
|
517
|
+
if (status.lockfiles.length === 0) {
|
|
518
|
+
report.manualActions.push(
|
|
519
|
+
'Generate and commit a dependency lockfile before deploying (for npm: run `npm install` and commit `package-lock.json`).'
|
|
520
|
+
);
|
|
521
|
+
}
|
|
480
522
|
}
|
|
481
523
|
|
|
482
524
|
function printList(title, items) {
|
|
@@ -503,9 +545,10 @@ function printSummary() {
|
|
|
503
545
|
console.log('2. Copy `.env.local.example` to `.env.local`, fill secrets, and keep `.env.example` as the team-facing public template.');
|
|
504
546
|
console.log('3. Copy `.dev.vars.example` to `.dev.vars` if you need local Wrangler secrets.');
|
|
505
547
|
console.log('4. Confirm `wrangler.toml` matches your Cloudflare Pages project name.');
|
|
506
|
-
console.log('5.
|
|
507
|
-
console.log('6. Run `
|
|
508
|
-
console.log('7. Run `node scripts/deploy-
|
|
548
|
+
console.log('5. Commit your dependency lockfile so Cloudflare Pages installs the same dependency tree.');
|
|
549
|
+
console.log('6. Run `npm run build` to verify static generation now runs before `vite build`.');
|
|
550
|
+
console.log('7. Run `node scripts/deploy-secrets.js` when you are ready to sync allowed env vars to Cloudflare Pages.');
|
|
551
|
+
console.log('8. Run `node scripts/deploy-pages.js` (or `npm run deploy:pages`) to build and deploy via Wrangler.');
|
|
509
552
|
}
|
|
510
553
|
|
|
511
554
|
try {
|
package/docs/AI-MASTER-PROMPT.md
CHANGED
|
@@ -14,6 +14,7 @@ Build a DigiValt consumer app with React, TypeScript, Vite, Tailwind, and Cloudf
|
|
|
14
14
|
- Render WordPress page bodies with `DigiValtWpPage` or `createContentRegistry` from `@marvalt/digivalt-core/registry`.
|
|
15
15
|
- Read app chrome with `getAppChrome()` from `@marvalt/digivalt-core/static`.
|
|
16
16
|
- Keep `functions/`, `wrangler.toml`, SEO helpers, sitemap + robots Functions, prerender script, and generated sitemap flow enabled.
|
|
17
|
+
- Generate and commit the package-manager lockfile. For npm, do not ignore `package-lock.json`; Cloudflare Pages must install the tested tree rather than re-resolve dependency ranges.
|
|
17
18
|
- Never commit `.env`, `.env.local`, `.env.*.local`, or `.dev.vars`.
|
|
18
19
|
- Update `public/sitemap-static-paths.json` for public app routes. Never hand-edit generated `public/sitemap-paths.json`.
|
|
19
20
|
|
package/docs/README.md
CHANGED
|
@@ -7,7 +7,8 @@ Read these in order for DigiValt app setup, deploy, and SEO.
|
|
|
7
7
|
| [ENVIRONMENT.md](./ENVIRONMENT.md) | Devs + DevOps | Env vars, `.env` model, Cloudflare secrets, React 19 install |
|
|
8
8
|
| [AI-LOCAL-WORDPRESS-BOOTSTRAP.md](./AI-LOCAL-WORDPRESS-BOOTSTRAP.md) | Humans | Local WordPress handover runbook |
|
|
9
9
|
| [AI-MASTER-PROMPT.md](./AI-MASTER-PROMPT.md) | AI tools | Vite + Cloudflare scaffold prompt |
|
|
10
|
-
| [SEO-
|
|
10
|
+
| [SEO-AIO.md](./SEO-AIO.md) | Devs + AI | End-to-end SEO/AIO: WP plugin, env, `DigiValtRouteSeo`, generate, prerender |
|
|
11
|
+
| [SEO-PERFORMANCE.md](./SEO-PERFORMANCE.md) | Devs | `VITE_SEO_*` table, sitemap XML, PageSpeed |
|
|
11
12
|
| [PATH-MOUNT.md](./PATH-MOUNT.md) | Devs | Path mounts via digivalt-uworker + Vite `base` + `withBasePath` |
|
|
12
13
|
| [CLOUDFLARE-STREAM.md](./CLOUDFLARE-STREAM.md) | Devs | Stream helpers + `CloudflareStreamPlayer` (`/media`) |
|
|
13
14
|
| [SHORTCODES.md](./SHORTCODES.md) | Devs + editors | How WP shortcodes are parsed and merged; links to adapter docs |
|
|
@@ -20,7 +21,7 @@ Package root [README.md](../README.md) covers `digivalt-init`, generators, and e
|
|
|
20
21
|
| Subpath | Use |
|
|
21
22
|
|---------|-----|
|
|
22
23
|
| `@marvalt/digivalt-core/generators` | Build-time static data (`generateAllData`) |
|
|
23
|
-
| `@marvalt/digivalt-core/seo` | `DigiValtSeoHead`, JSON-LD helpers |
|
|
24
|
+
| `@marvalt/digivalt-core/seo` | `DigiValtRouteSeo`, `DigiValtSeoHead`, JSON-LD helpers |
|
|
24
25
|
| `@marvalt/digivalt-core/registry` | Page-body registry, `DigiValtWpPage`, providers |
|
|
25
26
|
| `@marvalt/digivalt-core/integrations` | Browser-only: `DigiValtTracker`, `MauticTracking`, `ChatwootWidget` |
|
|
26
27
|
| `@marvalt/digivalt-core/media` | Cloudflare Stream helpers + `CloudflareStreamPlayer` |
|
package/docs/SEO-AIO.md
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# SEO / AIO in DigiValt apps
|
|
2
|
+
|
|
3
|
+
Playbook for **developers and AI agents** wiring `@marvalt/digivalt-core` with the **DigiValt SEO** WordPress plugin. Content-manager steps: `digivalt-collaboration-docs/DIGIVALT_SEO_AIO.md`. Env tables and PageSpeed: [SEO-PERFORMANCE.md](./SEO-PERFORMANCE.md). REST field list: WordPress plugin `digivalt-seo/README.md`.
|
|
4
|
+
|
|
5
|
+
## What “good” looks like
|
|
6
|
+
|
|
7
|
+
- **Site identity** in `VITE_SEO_*` (one set per frontend / Cloudflare project).
|
|
8
|
+
- **Per-URL** overrides in WordPress `digivalt_seo` (pages, posts, public REST CPTs).
|
|
9
|
+
- **Same HTML** for humans and crawlers: prerender snapshots, not user-agent cloaking, not Yoast.
|
|
10
|
+
- Visible copy and JSON-LD stay in sync (same generate JSON).
|
|
11
|
+
|
|
12
|
+
## Install
|
|
13
|
+
|
|
14
|
+
| Piece | Action |
|
|
15
|
+
|-------|--------|
|
|
16
|
+
| WordPress | Activate **DigiValt SEO**. Editors get a meta box and a Dashboard widget. |
|
|
17
|
+
| App | `@marvalt/digivalt-core` with `react-helmet-async`. `npx digivalt-init` for sitemap/robots Functions and `scripts/prerender-seo.ts`. |
|
|
18
|
+
| PageSync | Plugin ≥ 1.1.2 if briefs should seed `_digivalt_seo_*` meta. |
|
|
19
|
+
|
|
20
|
+
## Env vs WordPress
|
|
21
|
+
|
|
22
|
+
Keep in env: `VITE_SEO_SITE_URL`, `SITE_NAME`, `DEFAULT_*`, Twitter/Facebook, verification, optional `VITE_SEO_ROUTE_PREFIXES`, `VITE_SEO_FRONT_PAGE_SLUG`, `VITE_PHPLIST_NEWSLETTER_ROUTE_BASE`.
|
|
23
|
+
|
|
24
|
+
Never put per-page title/description in env.
|
|
25
|
+
|
|
26
|
+
## App checklist
|
|
27
|
+
|
|
28
|
+
```tsx
|
|
29
|
+
import { DigiValtRouteSeo } from '@marvalt/digivalt-core/seo';
|
|
30
|
+
|
|
31
|
+
<DigiValtRouteSeo pathname="/about" entity={page} />
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
- One instance per route. Pass the WordPress object from static JSON (`digivalt_seo` is already on it after generate).
|
|
35
|
+
- Utility routes (`subscribe`, `preferences`, 404): `noindex` and **omit** from `sitemap-static-paths.json`.
|
|
36
|
+
- Front page: app `/` + `VITE_SEO_FRONT_PAGE_SLUG` or WP Reading Settings `front_page`, never also `/<frontpage-slug>` in the sitemap.
|
|
37
|
+
|
|
38
|
+
`resolvePageSeo` / `buildPageJsonLd` if you need props without the React helper.
|
|
39
|
+
|
|
40
|
+
## Generate and deploy
|
|
41
|
+
|
|
42
|
+
`generateAllData()` (including fixture mode) writes:
|
|
43
|
+
|
|
44
|
+
- `public/sitemap-paths.json` — `{ urls: [{ path, lastmod?, image? }] }`
|
|
45
|
+
- `public/seo-manifest.json` — titles, descriptions, JSON-LD, body HTML for snapshots
|
|
46
|
+
|
|
47
|
+
Then `vite build` then `prerenderSeoHtml()` → `dist/index.html` and `dist/{path}/index.html`.
|
|
48
|
+
|
|
49
|
+
Cloudflare Pages Functions serve `/sitemap.xml` and `/robots.txt`. Do not commit those as static files.
|
|
50
|
+
|
|
51
|
+
CPT URLs other than pages are **opt-in**: `VITE_SEO_ROUTE_PREFIXES=eventbrite_event:/events,member:/members/profile`.
|
|
52
|
+
|
|
53
|
+
## AI agents: do not
|
|
54
|
+
|
|
55
|
+
- Do not add Yoast/Rank Math.
|
|
56
|
+
- Do not serve different HTML to bots vs users.
|
|
57
|
+
- Do not invent `changefreq` / `priority`.
|
|
58
|
+
- Do not hand-edit `sitemap-paths.json` or `seo-manifest.json`.
|
|
59
|
+
- Do not register DigiValt SEO fields as WordPress PHP shortcodes.
|
package/docs/SEO-PERFORMANCE.md
CHANGED
|
@@ -2,6 +2,8 @@
|
|
|
2
2
|
|
|
3
3
|
This guide is for **Vite + React** apps that use DigiValt static generation. It complements WordPress content with **document metadata**, **structured data**, and **performance-minded image/font patterns**.
|
|
4
4
|
|
|
5
|
+
**How the system fits together** (WP vs env, prerender, editor workflow): **[SEO-AIO.md](./SEO-AIO.md)**. Team handbook: `digivalt-collaboration-docs/DIGIVALT_SEO_AIO.md`.
|
|
6
|
+
|
|
5
7
|
## Prerequisites
|
|
6
8
|
|
|
7
9
|
1. Install the peer dependency (required for `DigiValtSeoHead`):
|
package/package.json
CHANGED
|
@@ -62,6 +62,9 @@ VITE_AUTH_MODE="direct"
|
|
|
62
62
|
|
|
63
63
|
## 🌩️ 5. Deploy Infrastructure to Cloudflare
|
|
64
64
|
Once you connect this GitHub repository to the Cloudflare Pages dashboard:
|
|
65
|
+
|
|
66
|
+
Before connecting the build, generate and commit your dependency lockfile. For npm, run `npm install`, ensure `.gitignore` does **not** exclude `package-lock.json`, and commit it. Pages must install the tested dependency tree rather than resolve fresh `^` ranges on every deployment.
|
|
67
|
+
|
|
65
68
|
1. Open `wrangler.toml` and change `name="digivalt-landing-api"` to match the exact name of your Cloudflare Pages project.
|
|
66
69
|
2. Run this automated script to inject your allowed DigiVAlt `.env` / `.env.local` variables into Cloudflare Pages:
|
|
67
70
|
```bash
|
|
@@ -73,6 +76,7 @@ node scripts/deploy-secrets.js
|
|
|
73
76
|
Rerun `npx digivalt-init` after upgrading `@marvalt/digivalt-core` when DigiVAlt-managed scaffolding changes.
|
|
74
77
|
|
|
75
78
|
Init will:
|
|
79
|
+
- report a missing dependency lockfile or a `package-lock.json` excluded by `.gitignore`
|
|
76
80
|
- patch safe `package.json` script cases automatically
|
|
77
81
|
- refresh older DigiVAlt-managed `scripts/generate.ts` files
|
|
78
82
|
- reconcile the DigiValt-managed sections inside `.env.example` and `.env.local.example`
|