diff --git a/packages/analytics/README.md b/packages/analytics/README.md
index 35a7b95..5104d56 100644
--- a/packages/analytics/README.md
+++ b/packages/analytics/README.md
@@ -11,11 +11,23 @@ entry that earned them rather than to a URL string.
> and an Analytics panel in the entry editor. Tested on EmDash 0.39 and 0.40.
> See "Not in this version".
+The screenshots show demo data on a site made from EmDash's blog template.
+
+## The dashboard widget
+
+A **Traffic** card on the dashboard: visits and page views for the last
+seven days against the week before, the five most viewed pages with the
+entry they belong to, and when the numbers were last synced.
+
+
+
## The Analytics page
**Plugins → Analytics** in the admin sidebar, or "Open analytics" on the
dashboard widget. Editors and admins see it.
+
+
The page asks the provider live on every load, so it has numbers from the
first minute after setup; it does not wait for the sync. It only ever asks
for the days the provider still counts exactly (for Cloudflare, the last
@@ -55,9 +67,14 @@ views, so the right one can be copied into the settings.
The check only reads; values are entered in the plugin's settings form. It
makes one request to Cloudflare.
+
+
## Analytics per entry
**Plugins → Analytics per entry**, or "Per entry" on the Analytics page.
+
+
+
Every published entry with its page views over the last 7 and 30 days,
today included, by collection or across all of them. Click a column header
to sort; sorting ascending puts the entries nobody visited first, which
@@ -84,6 +101,8 @@ URL.
## The editor panel
+
+
In the entry editor, the **Analytics** panel shows that entry's 7- and 30-day
page views and the path they are counted at, and on a translated entry
each language's numbers and their total. An entry that is not published
@@ -97,6 +116,7 @@ at a public URL says so instead.
| A Cloudflare account | with Web Analytics enabled for the site |
| An API token | permission **Account → Account Analytics → Read** |
| `EMDASH_ENCRYPTION_KEY` | set on the site, or the API token cannot be stored (`npx emdash secrets generate`) |
+| URL patterns | each collection needs a **URL Pattern** (under Content Types), or no page can be matched to its entry. Sites made from EmDash's blog template start without them; the setup check says so |
| Scheduled tasks | the sync runs as a plugin cron task. On Cloudflare Workers that needs the Cron Trigger and `scheduled` handler from EmDash's Cloudflare deployment guide; on Node, EmDash runs them itself |
### The token scope, precisely
diff --git a/packages/analytics/emdash-plugin.jsonc b/packages/analytics/emdash-plugin.jsonc
index 73b7a53..49b36ff 100644
--- a/packages/analytics/emdash-plugin.jsonc
+++ b/packages/analytics/emdash-plugin.jsonc
@@ -16,7 +16,16 @@
// break. The manifest has no advisory "tested up to" field to express
// caution without blocking, so the tested range belongs in the README.
"release": {
- "requires": { "env:emdash": ">=0.39.0" }
+ "requires": { "env:emdash": ">=0.39.0" },
+ "artifacts": {
+ "screenshots": [
+ { "file": "screenshots/analytics-page.png", "lang": "en" },
+ { "file": "screenshots/per-entry.png", "lang": "en" },
+ { "file": "screenshots/widget.png", "lang": "en" },
+ { "file": "screenshots/editor-panel.png", "lang": "en" },
+ { "file": "screenshots/setup-check.png", "lang": "en" }
+ ]
+ }
},
// Registry search indexes slug and description and has no keywords
// field, so every provider this plugin supports has to be named here.
diff --git a/packages/analytics/screenshots/analytics-page.png b/packages/analytics/screenshots/analytics-page.png
new file mode 100644
index 0000000..8a9e0c6
Binary files /dev/null and b/packages/analytics/screenshots/analytics-page.png differ
diff --git a/packages/analytics/screenshots/editor-panel.png b/packages/analytics/screenshots/editor-panel.png
new file mode 100644
index 0000000..ae752c7
Binary files /dev/null and b/packages/analytics/screenshots/editor-panel.png differ
diff --git a/packages/analytics/screenshots/per-entry.png b/packages/analytics/screenshots/per-entry.png
new file mode 100644
index 0000000..893d606
Binary files /dev/null and b/packages/analytics/screenshots/per-entry.png differ
diff --git a/packages/analytics/screenshots/setup-check.png b/packages/analytics/screenshots/setup-check.png
new file mode 100644
index 0000000..137dbc9
Binary files /dev/null and b/packages/analytics/screenshots/setup-check.png differ
diff --git a/packages/analytics/screenshots/widget.png b/packages/analytics/screenshots/widget.png
new file mode 100644
index 0000000..d642e8d
Binary files /dev/null and b/packages/analytics/screenshots/widget.png differ
diff --git a/packages/analytics/src/i18n.ts b/packages/analytics/src/i18n.ts
index 442d9e8..c26cd45 100644
--- a/packages/analytics/src/i18n.ts
+++ b/packages/analytics/src/i18n.ts
@@ -69,7 +69,7 @@ const en = {
noEntriesYet: "No entries yet",
noEntriesIndexing: "The content index is still being built. Entries appear as it progresses.",
noEntriesNoUrls:
- "No published entry has a public URL. Check that the site URL is set in EmDash and that the collections have URL patterns.",
+ "No published entry has a public URL. Check that the site URL is set in EmDash and that each collection has a URL Pattern (under Content Types), then press Rebuild index on the per-entry page.",
noEntriesHere: "No published entries here.",
panelNoPage: "No page for this entry yet",
panelNoPageDetail: "Views appear once the entry is published at a public URL and the next sync has run.",
@@ -123,7 +123,7 @@ const en = {
hostsNone:
"Cloudflare reports this site tag under {reported}, but the plugin counts only {counted}. Change Hostnames to count in the plugin's settings.",
siteUrlMissing:
- "EmDash has no site URL stored, so entries have no public address and page views cannot be matched to them. EmDash stores it (the emdash:site_url option) when the setup wizard runs on the live domain.",
+ "EmDash has no site URL, so entries have no public address and page views cannot be matched to them. EmDash stores it (the emdash:site_url option) when the setup wizard runs on the live domain; a server that was already running picks it up after a restart.",
needsSiteUrl: "Needs the site URL.",
indexMatched: { one: "{count} entry matched to its page.", other: "{count} entries matched to their pages." },
schedulerNotScheduled: "The sync is not scheduled yet. Opening the dashboard schedules it.",
@@ -254,7 +254,7 @@ const de: Record = {
noEntriesYet: "Noch keine Einträge",
noEntriesIndexing: "Der Inhaltsindex wird noch aufgebaut. Einträge erscheinen nach und nach.",
noEntriesNoUrls:
- "Kein veröffentlichter Eintrag hat eine öffentliche URL. Prüfe, ob die URL der Webseite in EmDash eingetragen ist und die Kollektionen URL-Muster haben.",
+ "Kein veröffentlichter Eintrag hat eine öffentliche URL. Prüfe, ob die URL der Website in EmDash eingetragen ist und jede Kollektion ein URL-Muster hat (unter Inhaltstypen), und drücke dann „Index neu aufbauen“ auf der Seite pro Eintrag.",
noEntriesHere: "Hier gibt es keine veröffentlichten Einträge.",
panelNoPage: "Noch keine Seite für diesen Eintrag",
panelNoPageDetail:
@@ -310,7 +310,7 @@ const de: Record = {
hostsNone:
"Cloudflare meldet dieses Site-Tag unter {reported}, das Plugin zählt aber nur {counted}. Ändere Hostnames to count in den Einstellungen des Plugins.",
siteUrlMissing:
- "EmDash hat keine Website-URL gespeichert, deshalb haben Einträge keine öffentliche Adresse und Seitenaufrufe lassen sich ihnen nicht zuordnen. EmDash speichert sie (die Option emdash:site_url), wenn der Einrichtungsassistent auf der Live-Domain läuft.",
+ "EmDash hat keine Website-URL, deshalb haben Einträge keine öffentliche Adresse und Seitenaufrufe lassen sich ihnen nicht zuordnen. EmDash speichert sie (die Option emdash:site_url), wenn der Einrichtungsassistent auf der Live-Domain läuft; ein Server, der da schon lief, übernimmt sie nach einem Neustart.",
needsSiteUrl: "Braucht die Website-URL.",
indexMatched: {
one: "{count} Eintrag ist seiner Seite zugeordnet.",
diff --git a/packages/analytics/tests/setup.test.ts b/packages/analytics/tests/setup.test.ts
index b599ba9..d105aba 100644
--- a/packages/analytics/tests/setup.test.ts
+++ b/packages/analytics/tests/setup.test.ts
@@ -129,7 +129,10 @@ describe("each failure, with the sentence that names its fix", () => {
it("a finished index that matched nothing although the URL is set", () => {
const facts = { ...healthy(), state: { ...healthy().state, indexed: 0 } };
- expect(check(facts, "index")).toMatchObject({ status: "problem", detail: expect.stringMatching(/URL patterns/) });
+ expect(check(facts, "index")).toMatchObject({
+ status: "problem",
+ detail: expect.stringMatching(/URL Pattern \(under Content Types\), then press Rebuild index/),
+ });
});
it("a host without a scheduler", () => {