@aeptus/aexeo-emdash 0.1.0 → 0.1.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.
- package/CHANGELOG.md +69 -8
- package/INSTALL.md +91 -4
- package/dist/configured.d.ts +8 -1
- package/dist/configured.d.ts.map +1 -1
- package/dist/configured.js +21 -11
- package/dist/index.d.ts +21 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +15 -5
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -6,6 +6,58 @@ and the project follows [Semantic Versioning](https://semver.org/).
|
|
|
6
6
|
|
|
7
7
|
## [Unreleased]
|
|
8
8
|
|
|
9
|
+
## [0.1.2] - 2026-04-28
|
|
10
|
+
|
|
11
|
+
Functional patch. Three bugs flagged by the aeptus web team after
|
|
12
|
+
testing 0.1.1 against emdash 0.8.0; same `wasm/` as `0.1.0` (no
|
|
13
|
+
rule-engine change).
|
|
14
|
+
|
|
15
|
+
**Compatibility:** verified against emdash `0.7.0` and `0.8.0`.
|
|
16
|
+
|
|
17
|
+
### Fixed
|
|
18
|
+
|
|
19
|
+
- **Duplicate "SEO findings" sidebar entry.** The descriptor and
|
|
20
|
+
the runtime admin both declared `/` AND `/findings` as adminPages
|
|
21
|
+
with the same label, so emdash rendered two duplicate links.
|
|
22
|
+
Drop the `/` entry — root-URL navigation
|
|
23
|
+
(`/admin/plugins/<id>/`) still works because the dispatcher in
|
|
24
|
+
`src/configured.ts` aliases the empty page name to the findings
|
|
25
|
+
page.
|
|
26
|
+
|
|
27
|
+
### Added
|
|
28
|
+
|
|
29
|
+
- **`seogeoPlugin({ collections })` option** for configured mode.
|
|
30
|
+
Lets sites with non-default collection slugs override which
|
|
31
|
+
collections the Refresh button sweeps. Defaults to
|
|
32
|
+
`["posts", "pages"]` when omitted (the slugs from
|
|
33
|
+
`@emdash-cms/template-blog-cloudflare`). Pointing at a missing
|
|
34
|
+
slug is non-fatal — the bridge returns empty and the sweep
|
|
35
|
+
records the missing collection in the Refresh summary's `errors`.
|
|
36
|
+
- The Refresh sweep now threads the resolved collection list
|
|
37
|
+
through `handleAdminRoute` → `handleRefresh` →
|
|
38
|
+
`evaluateAndPersistAll` so the runtime honors what the descriptor
|
|
39
|
+
passed.
|
|
40
|
+
|
|
41
|
+
## [0.1.1] - 2026-04-28
|
|
42
|
+
|
|
43
|
+
Documentation-only patch. No runtime changes — same `dist/` and
|
|
44
|
+
`wasm/` as `0.1.0`. Bumping the patch so npm consumers can resolve
|
|
45
|
+
to the documented version of INSTALL.md / CHANGELOG.md without
|
|
46
|
+
having to read this repo directly.
|
|
47
|
+
|
|
48
|
+
### Changed
|
|
49
|
+
|
|
50
|
+
- INSTALL.md now has a structured "Updating" section covering
|
|
51
|
+
routine plugin updates, emdash updates, joint updates, and the
|
|
52
|
+
verification steps for each. Establishes the rule "update one
|
|
53
|
+
thing at a time, never both in the same deploy" so failure
|
|
54
|
+
bisects stay clean.
|
|
55
|
+
- CHANGELOG.md compatibility section calls out the verified emdash
|
|
56
|
+
range explicitly (`0.7.0` and `0.8.0`), names the upstream PR
|
|
57
|
+
(#734) that fixes the sandboxed-mode `content:afterSave` bridge
|
|
58
|
+
bug on `0.8.0`, and sets the convention for future releases to
|
|
59
|
+
record their tested range the same way.
|
|
60
|
+
|
|
9
61
|
## [0.1.0] - 2026-04-28
|
|
10
62
|
|
|
11
63
|
First public release.
|
|
@@ -34,12 +86,21 @@ First public release.
|
|
|
34
86
|
|
|
35
87
|
### Compatibility
|
|
36
88
|
|
|
37
|
-
- emdash
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
89
|
+
- **emdash:** verified against `0.7.0` and `0.8.0`. Both modes work
|
|
90
|
+
on `0.7.0`; configured mode is recommended. On `0.8.0` the
|
|
91
|
+
sandboxed mode's `content:afterSave` hook also works (upstream
|
|
92
|
+
PR #734 wraps deferred plugin hooks in `after()` so bridge
|
|
93
|
+
bindings stay valid past the response — fixes the
|
|
94
|
+
silent-eval-skip behavior we worked around with the manual
|
|
95
|
+
Refresh button on `0.7.x`).
|
|
96
|
+
- **Adapter:** `@astrojs/cloudflare`. The plugin uses
|
|
97
|
+
Cloudflare-specific APIs and will silently no-op on the Node
|
|
98
|
+
adapter.
|
|
99
|
+
- **Vite plugin:** `vite-plugin-wasm` is required in the consumer's
|
|
100
|
+
`astro.config.mjs` for the WASM import to resolve to a
|
|
101
|
+
precompiled `WebAssembly.Module`. Not optional.
|
|
43
102
|
|
|
44
|
-
[Unreleased]: https://github.com/schiste/Aexeo/compare/
|
|
45
|
-
[0.1.
|
|
103
|
+
[Unreleased]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.1.2...HEAD
|
|
104
|
+
[0.1.2]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.1.1...aexeo-emdash-v0.1.2
|
|
105
|
+
[0.1.1]: https://github.com/schiste/Aexeo/compare/aexeo-emdash-v0.1.0...aexeo-emdash-v0.1.1
|
|
106
|
+
[0.1.0]: https://github.com/schiste/Aexeo/releases/tag/aexeo-emdash-v0.1.0
|
package/INSTALL.md
CHANGED
|
@@ -117,15 +117,102 @@ compiles into the deployed Worker artifact.
|
|
|
117
117
|
|
|
118
118
|
## Updating
|
|
119
119
|
|
|
120
|
+
There are two things that can be updated independently — the plugin
|
|
121
|
+
package and emdash itself. **Update one at a time, never both in the
|
|
122
|
+
same deploy.** That way if something breaks, you know which side
|
|
123
|
+
introduced the regression.
|
|
124
|
+
|
|
125
|
+
### Updating the plugin
|
|
126
|
+
|
|
127
|
+
For a routine patch / minor update within your existing semver range:
|
|
128
|
+
|
|
120
129
|
```bash
|
|
121
130
|
npm update @aeptus/aexeo-emdash
|
|
122
|
-
npm run build
|
|
131
|
+
npm run build
|
|
132
|
+
# Your usual deploy command
|
|
123
133
|
```
|
|
124
134
|
|
|
135
|
+
For a major version bump (e.g. from `^0.x` to `^1.x`):
|
|
136
|
+
|
|
137
|
+
1. Read the [CHANGELOG](./CHANGELOG.md) entry for the new major.
|
|
138
|
+
Look for the `Compatibility` line that names the verified
|
|
139
|
+
emdash version range — confirm it covers your installed emdash.
|
|
140
|
+
2. Bump the dependency range in `package.json`:
|
|
141
|
+
```diff
|
|
142
|
+
- "@aeptus/aexeo-emdash": "^0.1.0",
|
|
143
|
+
+ "@aeptus/aexeo-emdash": "^0.2.0",
|
|
144
|
+
```
|
|
145
|
+
3. `npm install`, build, deploy.
|
|
146
|
+
|
|
125
147
|
The plugin's WASM is bundled with each version of the package, so
|
|
126
|
-
`npm update` brings new rules along automatically.
|
|
127
|
-
separate sidecar to keep in sync (configured mode), no
|
|
128
|
-
rotate, no Setup page to revisit.
|
|
148
|
+
`npm update` / `npm install` brings new rules along automatically.
|
|
149
|
+
There's no separate sidecar to keep in sync (configured mode), no
|
|
150
|
+
token to rotate, no Setup page to revisit.
|
|
151
|
+
|
|
152
|
+
**Verify after a plugin update:**
|
|
153
|
+
|
|
154
|
+
1. Visit `/admin/plugins/aexeo-seogeo/findings` and click **Refresh**.
|
|
155
|
+
Toast should show non-zero rules sweeping. (A zero count *can*
|
|
156
|
+
be valid for a clean site, but if you previously had findings
|
|
157
|
+
and now have none, suspect the upgrade.)
|
|
158
|
+
2. Save any document — `/findings` should auto-update for that
|
|
159
|
+
route's findings (the `content:afterSave` hook firing).
|
|
160
|
+
|
|
161
|
+
### Updating emdash
|
|
162
|
+
|
|
163
|
+
Updating emdash is the more dangerous direction because emdash
|
|
164
|
+
controls the contracts the plugin depends on (PluginContext shape,
|
|
165
|
+
hook signatures, Block Kit schemas, capability strings, etc.).
|
|
166
|
+
Pre-flight before bumping:
|
|
167
|
+
|
|
168
|
+
1. Look up the plugin version's tested emdash range in our
|
|
169
|
+
[CHANGELOG](./CHANGELOG.md). The latest plugin version's
|
|
170
|
+
`Compatibility` line says e.g. "tested against emdash 0.7.0
|
|
171
|
+
through 0.8.0." If the emdash version you want is **inside that
|
|
172
|
+
range**, the bump is safe. If it's **above the range**, treat it
|
|
173
|
+
as untested.
|
|
174
|
+
2. If untested, scan the emdash release notes for breaking changes
|
|
175
|
+
in any of these areas (these are what the plugin touches):
|
|
176
|
+
- `PluginContext` shape (kv, http, content, log)
|
|
177
|
+
- Hook signatures (`content:afterSave`, etc.)
|
|
178
|
+
- Block Kit element schemas (banner variants, button styles,
|
|
179
|
+
table column formats)
|
|
180
|
+
- Capability validation strings (`read:content`, `network:fetch`)
|
|
181
|
+
- The `definePlugin` API
|
|
182
|
+
- The `createPlugin` / configured-plugin descriptor contract
|
|
183
|
+
If any of those changed, expect to bump the plugin too.
|
|
184
|
+
3. Bump emdash:
|
|
185
|
+
```bash
|
|
186
|
+
npm install emdash@<new-version>
|
|
187
|
+
```
|
|
188
|
+
4. Build and run locally first — never deploy directly to
|
|
189
|
+
production.
|
|
190
|
+
5. Verify the plugin: same two checks as above (Refresh + save).
|
|
191
|
+
|
|
192
|
+
If verification fails: roll emdash back
|
|
193
|
+
(`npm install emdash@<previous-version>`), file an issue against
|
|
194
|
+
this plugin describing the failure, and stay on the prior emdash
|
|
195
|
+
version until a compatible plugin release ships.
|
|
196
|
+
|
|
197
|
+
### When both need updating together
|
|
198
|
+
|
|
199
|
+
Sometimes a plugin release will require an emdash bump (because we
|
|
200
|
+
adopted a new emdash API). The plugin's CHANGELOG will say so:
|
|
201
|
+
"Requires emdash >= X.Y.0." When that's the case:
|
|
202
|
+
|
|
203
|
+
1. Update emdash first.
|
|
204
|
+
2. Verify the existing plugin still works on the new emdash.
|
|
205
|
+
3. Update the plugin.
|
|
206
|
+
4. Verify again.
|
|
207
|
+
|
|
208
|
+
Two separate deploys, two separate verification passes. This
|
|
209
|
+
keeps the bisect clean if anything breaks.
|
|
210
|
+
|
|
211
|
+
### Compatibility quick-reference
|
|
212
|
+
|
|
213
|
+
The current verified pairing is recorded in
|
|
214
|
+
[CHANGELOG.md](./CHANGELOG.md) at the top of each release entry.
|
|
215
|
+
Treat anything outside that range as best-effort.
|
|
129
216
|
|
|
130
217
|
## Removing
|
|
131
218
|
|
package/dist/configured.d.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
export interface ConfiguredPluginOptions {
|
|
2
|
+
/**
|
|
3
|
+
* emdash collections the Refresh button sweeps. Comes through from
|
|
4
|
+
* the descriptor's `options` field — see `seogeoPlugin({ collections })`
|
|
5
|
+
* in src/index.ts. When undefined, falls back to DEFAULT_COLLECTIONS
|
|
6
|
+
* (`["posts", "pages"]`).
|
|
7
|
+
*/
|
|
8
|
+
collections?: readonly string[];
|
|
2
9
|
}
|
|
3
|
-
export declare function createPlugin(
|
|
10
|
+
export declare function createPlugin(options?: ConfiguredPluginOptions): unknown;
|
|
4
11
|
export default createPlugin;
|
|
5
12
|
//# sourceMappingURL=configured.d.ts.map
|
package/dist/configured.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"configured.d.ts","sourceRoot":"","sources":["../src/configured.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"configured.d.ts","sourceRoot":"","sources":["../src/configured.ts"],"names":[],"mappings":"AA6EA,MAAM,WAAW,uBAAuB;IACtC;;;;;OAKG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,YAAY,CAAC,OAAO,GAAE,uBAA4B,GAAG,OAAO,CAmD3E;AAID,eAAe,YAAY,CAAC"}
|
package/dist/configured.js
CHANGED
|
@@ -357,24 +357,33 @@ var inProcessEvaluator = async (documents) => {
|
|
|
357
357
|
return { ok: false, reason: "wasm_error", detail };
|
|
358
358
|
}
|
|
359
359
|
};
|
|
360
|
-
function createPlugin(
|
|
360
|
+
function createPlugin(options = {}) {
|
|
361
|
+
const collections = options.collections === void 0 ? DEFAULT_COLLECTIONS : [...options.collections];
|
|
361
362
|
return definePlugin({
|
|
362
363
|
id: "aexeo-seogeo",
|
|
363
364
|
version: "0.0.1",
|
|
364
365
|
capabilities: ["read:content"],
|
|
365
366
|
hooks: {
|
|
367
|
+
// afterSave processes one saved document at a time — collections
|
|
368
|
+
// list isn't needed here. The hook always runs regardless of
|
|
369
|
+
// which collection the document came from.
|
|
366
370
|
"content:afterSave": (event, ctx) => handleAfterSaveConfigured(event, ctx, inProcessEvaluator)
|
|
367
371
|
},
|
|
368
372
|
routes: {
|
|
369
|
-
|
|
373
|
+
// The Refresh sweep (handleAdminRoute → handleRefresh) is the
|
|
374
|
+
// one consumer of `collections`. Bind the resolved list here so
|
|
375
|
+
// every request handles the same set without re-reading options.
|
|
376
|
+
admin: {
|
|
377
|
+
handler: (ctx) => handleAdminRoute(ctx, collections)
|
|
378
|
+
}
|
|
370
379
|
},
|
|
371
380
|
admin: {
|
|
372
381
|
pages: [
|
|
373
|
-
//
|
|
374
|
-
//
|
|
375
|
-
//
|
|
376
|
-
//
|
|
377
|
-
|
|
382
|
+
// The root URL `/admin/plugins/<id>/` routes through the same
|
|
383
|
+
// dispatcher (handlePageLoad treats "" and "findings" as
|
|
384
|
+
// aliases). Listing "/" alongside "/findings" here would create
|
|
385
|
+
// duplicate "SEO findings" sidebar entries — that was the
|
|
386
|
+
// visible 0.1.0 / 0.1.1 bug fixed in 0.1.2.
|
|
378
387
|
{ path: "/findings", label: "SEO findings" },
|
|
379
388
|
{ path: "/document", label: "Document SEO" }
|
|
380
389
|
],
|
|
@@ -385,7 +394,7 @@ function createPlugin(_options = {}) {
|
|
|
385
394
|
});
|
|
386
395
|
}
|
|
387
396
|
var configured_default = createPlugin;
|
|
388
|
-
async function handleAdminRoute(ctx) {
|
|
397
|
+
async function handleAdminRoute(ctx, collections) {
|
|
389
398
|
const body = ctx.input;
|
|
390
399
|
if (body.type === "page_load") {
|
|
391
400
|
return handlePageLoad(ctx, body.page);
|
|
@@ -395,7 +404,7 @@ async function handleAdminRoute(ctx) {
|
|
|
395
404
|
return renderDocumentPanel(ctx, body.value);
|
|
396
405
|
}
|
|
397
406
|
if (body.action_id === "refresh_findings") {
|
|
398
|
-
return handleRefresh(ctx);
|
|
407
|
+
return handleRefresh(ctx, collections);
|
|
399
408
|
}
|
|
400
409
|
if (body.action_id.startsWith("filter:")) {
|
|
401
410
|
return renderFindingsPage(ctx);
|
|
@@ -426,11 +435,12 @@ async function handlePageLoad(ctx, page) {
|
|
|
426
435
|
}
|
|
427
436
|
return notFound(page);
|
|
428
437
|
}
|
|
429
|
-
async function handleRefresh(ctx) {
|
|
438
|
+
async function handleRefresh(ctx, collections) {
|
|
430
439
|
let summary;
|
|
431
440
|
try {
|
|
432
441
|
summary = await evaluateAndPersistAll(ctx, {
|
|
433
|
-
evaluator: inProcessEvaluator
|
|
442
|
+
evaluator: inProcessEvaluator,
|
|
443
|
+
collections
|
|
434
444
|
});
|
|
435
445
|
} catch (err) {
|
|
436
446
|
const detail = err instanceof Error ? err.message : String(err);
|
package/dist/index.d.ts
CHANGED
|
@@ -18,6 +18,27 @@ export interface ConfiguredPluginDescriptor {
|
|
|
18
18
|
}[];
|
|
19
19
|
}
|
|
20
20
|
export interface SeogeoPluginOptions {
|
|
21
|
+
/**
|
|
22
|
+
* emdash collections the plugin sweeps when an admin clicks
|
|
23
|
+
* Refresh on the findings page. Order doesn't matter; the sweep
|
|
24
|
+
* iterates each collection sequentially and groups findings by
|
|
25
|
+
* document route. The per-document `content:afterSave` hook always
|
|
26
|
+
* runs regardless of this list — saving a document in any
|
|
27
|
+
* collection triggers an evaluation for that one document.
|
|
28
|
+
*
|
|
29
|
+
* Defaults to `["posts", "pages"]` (the slugs the
|
|
30
|
+
* `@emdash-cms/template-blog-cloudflare` template ships with).
|
|
31
|
+
* Override when your schema uses different collection slugs:
|
|
32
|
+
*
|
|
33
|
+
* seogeoPlugin({ collections: ["posts", "guides", "products"] })
|
|
34
|
+
*
|
|
35
|
+
* Pointing this at a slug that doesn't exist in your schema is
|
|
36
|
+
* non-fatal: the bridge's `content.list` returns empty and the
|
|
37
|
+
* sweep records the missing collection in the Refresh summary's
|
|
38
|
+
* `errors` field. Safe to ship a superset for a project that may
|
|
39
|
+
* add collections later.
|
|
40
|
+
*/
|
|
41
|
+
collections?: readonly string[];
|
|
21
42
|
}
|
|
22
43
|
export declare function seogeoPlugin(options?: SeogeoPluginOptions): ConfiguredPluginDescriptor;
|
|
23
44
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAWtB,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,UAAU,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,YAAY,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACxE;AAED,MAAM,WAAW,mBAAmB;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAqBA,OAAO,EAAE,qBAAqB,EAAE,MAAM,cAAc,CAAC;AACrD,YAAY,EACV,eAAe,EACf,iBAAiB,EACjB,yBAAyB,EACzB,sBAAsB,GACvB,MAAM,cAAc,CAAC;AAWtB,MAAM,WAAW,0BAA0B;IACzC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,EAAE,SAAS,MAAM,EAAE,CAAC;IAChC,YAAY,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACjC,UAAU,EAAE,SAAS;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IACvD,YAAY,EAAE,SAAS;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,KAAK,CAAC,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;CACxE;AAED,MAAM,WAAW,mBAAmB;IAClC;;;;;;;;;;;;;;;;;;;OAmBG;IACH,WAAW,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACjC;AAED,wBAAgB,YAAY,CAC1B,OAAO,GAAE,mBAAwB,GAChC,0BAA0B,CAsC5B"}
|
package/dist/index.js
CHANGED
|
@@ -57,17 +57,27 @@ function seogeoPlugin(options = {}) {
|
|
|
57
57
|
// time — must match the package.json `exports["./configured"]`
|
|
58
58
|
// entry.
|
|
59
59
|
entrypoint: "@aeptus/aexeo-emdash/configured",
|
|
60
|
-
|
|
60
|
+
// emdash's astro integration JSON-serializes `options` and emits
|
|
61
|
+
// an importer that does `createPlugin(<options>)` at boot.
|
|
62
|
+
// Anything we put here is what the runtime entry's createPlugin
|
|
63
|
+
// receives. Spread to a plain object so readonly arrays survive
|
|
64
|
+
// the structured-clone semantics of that codegen.
|
|
65
|
+
options: {
|
|
66
|
+
...options.collections === void 0 ? {} : { collections: [...options.collections] }
|
|
67
|
+
},
|
|
61
68
|
capabilities: [
|
|
62
69
|
"read:content",
|
|
63
70
|
"read:schema",
|
|
64
71
|
"kv:seogeo-baselines"
|
|
65
72
|
],
|
|
73
|
+
// adminPages drives the admin sidebar — one nav entry per item.
|
|
74
|
+
// Don't list "/" alongside "/findings": both would render as
|
|
75
|
+
// duplicate "SEO findings" links in the sidebar (0.1.0 / 0.1.1
|
|
76
|
+
// shipped with this duplicate; fixed in 0.1.2). The root URL
|
|
77
|
+
// /admin/plugins/<id>/ still routes correctly because the
|
|
78
|
+
// dispatcher in src/configured.ts treats "" and "findings" as
|
|
79
|
+
// the same page.
|
|
66
80
|
adminPages: [
|
|
67
|
-
// "/" alias is required so emdash's /admin/plugins/<id> root
|
|
68
|
-
// doesn't 404 — that page is where the meta /admin/plugins
|
|
69
|
-
// list links to when an operator clicks the plugin entry.
|
|
70
|
-
{ path: "/", label: "SEO findings" },
|
|
71
81
|
{ path: "/findings", label: "SEO findings" },
|
|
72
82
|
{ path: "/document", label: "Document SEO" }
|
|
73
83
|
],
|