<%= note.title %>
+ <% if (isEmpty && (!note.hasVisibleChildren() && note.type !== "book")) { %> +<%= t("share_page.no-content") %>
+ <% } else { %> + <% + content = content.replace(/diff --git a/AGENTS.md b/AGENTS.md index e39cd57..6a00798 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -91,6 +91,14 @@ CSS file (Gruvbox, light + dark, theme toggle without reload). `_thumb` child-note convention for small thumbnails. - Built-in share footer navigation and book children list are hidden (`#content-footer .navigation`, `#index`). +- **SEO**: a custom share template (`templates/share/page.ejs`, note `share template`, + `application/x-ejs`, wired via `~shareTemplate` inheritable on the blog root, with + `tree_item`/`prev_next`/`toc_item` partials as children) adds per-page canonical, + `og:url`/`og:image`/`og:type`, Twitter cards, JSON-LD (WebSite/BlogPosting/CollectionPage) + and `index,follow`. The generator's `ensureSeoMeta()` sets `shareDescription` + + `shareOpenGraphURL` on every published note and category. `robots.txt` + (`shareAlias=robots.txt`, `shareRaw`) points at the sitemap; `~shareOpenGraphImage` + on the blog root sets the default OG image. ## Limitations / gotchas diff --git a/README.md b/README.md index 29dccff..a4c2d60 100644 --- a/README.md +++ b/README.md @@ -38,6 +38,10 @@ no external dependencies (except `highlight.js`, vendored in `lib/`). - **Digital Garden**: `state` labels (Seed → Evergreen, Draft, Review) rendered as badges and colour-coded growth tables. - **Search** (client-side over a generated index), **RSS feed** and **sitemap.xml**. +- **SEO**: per-page canonical + Open Graph (`og:url`, `og:image`, article/website type), + Twitter cards, JSON-LD structured data (WebSite / BlogPosting / CollectionPage), + `robots.txt` and `index,follow` meta. Provided by a custom share template + (`templates/share/page.ejs`). - **Widget rendering** for Mermaid, Excalidraw (canvas) and MindElixir (mind map) notes, with a collapsible, highlighted "Source" block and copy button. - **3D models**: `.step` / `.stp` / `.stl` files (as file notes or inline attachments) render @@ -63,6 +67,8 @@ no external dependencies (except `highlight.js`, vendored in `lib/`). | `lib/hljs_line_numbers.js` | highlight.js line-numbers plugin | code | | `scripts/*.js` | frontend share snippets (content is pasted **verbatim** into a code note, including the ` + <% } %> + <% if (note.hasLabel("shareDisallowRobotIndexing")) { %> + + <% } else { %> + + <% } %> + + <% + const pageTitle = `${note.title}${note.noteId !== subRoot.note.noteId ? ` - ${subRoot.note.title}` : ""}`; + + const openGraphColor = subRoot.note.getLabelValue("shareOpenGraphColor"); + const openGraphDomain = subRoot.note.getLabelValue("shareOpenGraphDomain"); + %> +
<%= t("share_page.no-content") %>
+ <% } else { %> + <% + content = content.replace(/