Pages
SDK reference for pages operations
Overview
Dynamic page creation — create dashboards, reports, and interactive pages with React and Tailwind
- Category:
internal - Auth Required: No
- Supported Modes: standard, delegated
Operations
createPage
Create a new page with JSX code. The code is compiled to HTML with React, Tailwind CSS, Recharts, and Lucide icons available as globals. Define a top-level function App() component as the entry point. Do NOT use import/require statements — all libraries are pre-loaded via CDN. Use Recharts components directly (e.g. <BarChart>, <ResponsiveContainer>) and Lucide icons via lucide.IconName.
═══════════════════════════════════════════════════════════════ MIRRA STYLE GUIDE — READ BEFORE WRITING A SINGLE LINE OF JSX ═══════════════════════════════════════════════════════════════
Mirra's aesthetic is "Corporate Burple" — confident, restrained, modern. Think premium product surface meets editorial clarity. NOT generic SaaS dashboard. NOT Linear-clone-dark-gray. The brand is the only saturated thing on the page; everything else is a quiet neutral. Intentionality in every detail.
Pages render as web pages viewed on mobile AND desktop (not native apps). Design responsive-first with a clear content hierarchy.
── BRAND IDENTITY ────────────────────────────────────────────── Primary accent: BURPLE (#793BFF) — the brand violet. Used for CTAs, key data points, active states, chart highlights. Use it SPARINGLY for maximum impact — 5-10% of visible surface area, not 30%. Secondary accent: MINT (#A0F0D2 on dark). Optional, for a positive delta or a second emphasis. Never a third hue. Dark surfaces: near-neutral charcoal (#1A1A1E / #212126 / #2A2A30), NOT pure black, NOT navy, NOT violet-tinted — the neutrals sit near 7% saturation so the brand stays the only saturated thing on screen. Light surfaces: cool off-white (#F6F7FB / #FFFFFF), NOT pure gray, NOT cream. Text: #111318 on light, #EDEDF0 on dark.
── THEME TOKENS (use these, never raw colors) ────────────────── Backgrounds: bg-m-bg (page), bg-m-surface (cards), bg-m-surface-alt (nested) Text: text-m-text (primary), text-m-text-secondary, text-m-text-muted Borders: border-m-border (subtle, always), border-m-border-strong (emphasis) Accent: text-m-accent-text, bg-m-accent, bg-m-accent-soft (tinted wash) Secondary: text-m-mint, bg-m-mint — theme-aware, safe on both surfaces Brand ramp: bg-mirra-50 … bg-mirra-950 when you need a tint or shade of the brand Status: text-emerald-500 (up), text-rose-400 (down), text-amber-400 (warn) Charts: MIRRA_COLORS[0..7] — never hardcode hex fills Dark mode is DEFAULT. For light pages add data-theme="light" on the root div.
── TYPOGRAPHY ────────────────────────────────────────────────── font-display (Syne) — headings, hero numbers, stat values. Bold/extrabold. font-body (Inter) — body copy, labels, descriptions (default). font-mono — numeric data, percentages, timestamps, ids, code. Scale (web): hero 48-72px, h1 36-48px, h2 28-36px, h3 20-24px, body 15-17px, caption 12-13px. Tight tracking on headlines (tracking-tight or -0.02em). Sentence case, never ALL CAPS for headings. Short uppercase tracking-wide only for small labels. Line-height: 1.2-1.3 headings, 1.6-1.7 body.
── LAYOUT & SPACING (8pt grid) ───────────────────────────────── Centered content, max-w-6xl or max-w-7xl on desktop (1100-1280px), never edge-to-edge full-bleed text. Page padding: p-6 md:p-10 lg:p-16 — generous whitespace is the #1 visual difference between Mirra and AI-generated pages. Section rhythm: mb-12 md:mb-20 between major sections. Never cramped. Grid gaps: gap-4 (tight), gap-6 (standard), gap-8 (airy). Never gap-2 between cards. Corner radius: rounded-lg (8px) for small elements, rounded-xl (12-16px) for cards, rounded-2xl (20-24px) for feature blocks, rounded-full for pills/avatars. Consistent per page.
── SURFACES & DEPTH ──────────────────────────────────────────── Depth is structural, not drawn: stack the planes bg-m-bg → bg-m-surface → bg-m-surface-alt and let the step in value carry it. Borders only refine that seam. Prefer 1px subtle borders (border border-m-border) over shadows — shadows read as "AI generic." When using shadow, go low-opacity and neutral: shadow-sm or shadow-[0_1px_2px_rgba(0,0,0,0.06),0_8px_24px_rgba(0,0,0,0.08)]. Skip if unsure. Layering: bg-m-bg → bg-m-surface (card) → bg-m-surface-alt (nested row/chip). Don't stack more than 3 levels.
── MOTION ────────────────────────────────────────────────────── Use sparingly. transition-colors duration-200 on hover is enough. One well-orchestrated page-load stagger (opacity + translateY 8px, delay per index) > scattered micro-interactions. NEVER hover:scale-105 on cards — it's AI-tell #1.
── COMMIT TO A DIRECTION ─────────────────────────────────────── Before writing JSX, pick a concrete aesthetic stance for THIS page: editorial/magazine, data-dense terminal, minimal report, warm dashboard, playful toy, etc. Execute that stance consistently. Intentionality beats novelty.
── DO ────────────────────────────────────────────────────────── ✓ Use m-* tokens for every color. If you type "bg-slate" or "bg-gray" you're wrong. ✓ Use font-mono for EVERY number the user reads: prices, percentages, counts, dates, ids. ✓ Use generous padding (p-8 md:p-12) and max-width centering. ✓ Use the accent color as a highlight, not a fill. One or two accent moments per viewport. ✓ Use MIRRA_COLORS for chart fills/strokes, var(--m-border) for chart gridlines, var(--m-text-muted) for axis labels. ✓ Assign MIRRA_COLORS in slot order (0, 1, 2, …) and never cycle or shuffle — the order is what keeps series distinguishable to colorblind readers. Two series take slots 0 and 1, not "two colors that look nice together". A single series takes slot 0 and needs no legend. For scatter/bubble/small-multiples only the first THREE slots are safe; past that, fold the tail into "Other" or facet. ✓ Give any chart with 2+ series a legend, and direct-label up to 4 — identity must never rest on color alone. ✓ Use tabular-nums on numeric columns in tables. ✓ Use sentence case for all headings and labels. ✓ Build responsive-first: mobile stack → tablet 2-col → desktop 3-4 col.
── DO NOT (these are AI-generic "slop" tells) ────────────────── ✗ NO purple-to-blue or pink-to-purple gradients. NO "from-purple-500 to-blue-500." This is the #1 AI-slop giveaway — and it is NOT excused by the brand being violet. Burple is a flat accent, never a gradient stop. ✗ NO Tailwind's purple-500 / violet-500 / indigo-500 as a stand-in for the brand. The brand is bg-m-accent or the mirra-* ramp; a generic purple reads as the AI default, which is the opposite of branded. ✗ NO pure white (#FFFFFF) page backgrounds or pure black (#000). The page plane is bg-m-bg; #FFFFFF is a card surface in light mode, not a page. ✗ NO warm/sand/cream neutrals and NO violet-tinted greys. The neutral spine is near-neutral charcoal on dark, cool off-white on light — the brand is the only saturated thing on the page. ✗ NO hover:scale-105, hover:-translate-y-1, or bouncy card hover effects. ✗ NO emoji as bullet points or UI decoration (✨🚀💡). Use Lucide icons. ✗ NO bg-slate, bg-zinc, bg-gray, bg-neutral — use bg-m-* tokens. ✗ NO generic card grids of 3 identical boxes with icon-title-description. Vary sizes, weights, layouts. ✗ NO Space Grotesk, no Poppins, no Montserrat. Use font-display (Syne) / font-body (Inter) / font-mono. ✗ NO drop-shadow-2xl, no ring-4, no excessive glow/blur. Restraint. ✗ NO all-caps h1/h2. Reserve uppercase for tiny tracking-wide labels. ✗ NO centered body copy paragraphs. Center headings, left-align prose. ✗ NO placeholder lorem ipsum — use real content or the user's data. ✗ NO flashy intro animations or scroll-jacking.
If a page would look at home in a GPT-generated "SaaS landing page" demo, REJECT and redesign. Mirra pages should feel like a thoughtful designer crafted them.
Arguments:
path(string, required): URL path for the page (e.g. "/dashboard"). Must start with /, lowercase alphanumeric and hyphens only, 2-50 chars.title(string, optional): Display title for the page. Required unless codePath is provided (can be read from .meta.json).code(string, optional): Page source, in either format. JSX: must define a top-level function App() component, no import/require — React, ReactDOM, Recharts (BarChart, PieChart, LineChart, ResponsiveContainer, etc.), lucide-react, Tailwind CSS, and the Mirra design system (m-* color tokens, font-display/font-body/font-mono, MIRRA_COLORS array) are pre-loaded globals. HTML: a self-contained document with inline CSS/JS and no external requests — the Claude Artifact shape, stored and served verbatim, with no page shell and no data hooks. The format is detected automatically; passformatto be explicit. Required unless codePath is provided.format(string, optional): Force the source format: "jsx" or "html". Normally omitted — a document starting with <!doctype html> or <html> is treated as HTML and everything else as JSX.codePath(string, optional): Path to a source file in the workspace container (e.g., "/workspace/pages/dashboard.jsx" or ".../page.html"). If provided, code is read from this file. Optionally reads .meta.json from the same directory for title/visibility.description(string, optional): Optional description of the pagevisibility(string, optional): Page visibility: "private" (default) or "public"graphId(string, optional): Optional graph ID for the page's data source (e.g. a group graph for memory queries). The page URL stays under the caller's personal subdomain. The caller must be a member of the target graph.purpose(string, optional): Set to "poster" when the page is the 900x540 picture that leads an update card — one line or one number set very large, meant to be looked at rather than read. Posters are kept out of the artifacts library, because a library lists things people open and a poster is not one of them. Omit for every normal page.
Returns:
object - Created page with id, path, title, codeHash, visibility, and url
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
description | string | Page description (optional) |
codeHash | string | Hash of the compiled code |
visibility | string | Page visibility: "private" or "public" |
url | string | Public URL for the page |
accessInfo | string | Human-readable description of who can access the page |
lintWarnings | string | Lint warnings from code validation (optional) |
apiKey | string | API key for public pages (only shown once) (optional) |
Example:
createReportPage
Create a report page using the widget factory. Instead of writing JSX code, specify a structured widget spec and the system generates optimized JSX deterministically. Supports 11 widget types: stat-grid, bar-chart, line-chart, area-chart, pie-chart, table, list, metric-card, text-block, treemap, radar-chart. Each widget fetches data from a Data collection at runtime.
Arguments:
path(string, required): URL path for the page (e.g. "/sales-report"). Must start with /, lowercase alphanumeric and hyphens only.title(string, required): Display title for the report pagedescription(string, optional): Optional subtitle displayed below the titletheme(string, optional): Color theme: "dark" (default) or "light"layout(string, optional): Layout: "dashboard" (2-col grid, default), "report" (single-col max-w-4xl), "single-column" (full-width single-col)visibility(string, optional): Page visibility: "private" (default) or "public"widgets(array, required): Array of widget specs. Each widget has: type (string), collection (Data collection slug), transform (optional: { type:"raw"|"groupBy"|"timeSeries", ... }), display ({ title?, height?, colorIndex? }), config (type-specific fields).
Widget types and config:
- stat-grid: { columns, items: [{ label, valueField, format?, aggregate? }] }
- bar-chart: { xField, yField, orientation?, stacked? }
- line-chart: { xField, yFields[], smooth? }
- area-chart: { xField, yFields[], stacked? }
- pie-chart: { labelField, valueField, donut? }
- table: { columns: [{ field, label, format?, align? }], limit? }
- list: { titleField, subtitleField?, metaField?, metaFormat?, limit? }
- metric-card: { valueField, label, format? }
- text-block: { content }
- treemap: { nameField, valueField }
- radar-chart: { axisField, valueFields[] }
Transform types:
- raw: { sort?: { field, direction }, limit? }
- groupBy: { field, metric: { field, op:
"sum"|"avg"|"count"|"min"|"max"}, sort?, limit? } - timeSeries: { timeField, granularity?:
"day"|"week"|"month"}
Returns:
object - Created page with id, path, title, widgetCount, codeHash, url
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
widgetCount | number | Number of widgets on the page |
codeHash | string | Hash of the compiled code |
visibility | string | Page visibility: "private" or "public" |
url | string | Public URL for the page |
accessInfo | string | Human-readable description of who can access the page |
lintWarnings | string | Lint warnings from code validation (optional) |
apiKey | string | API key for public pages (only shown once) (optional) |
Example:
upsertReportPage
Create or update a report page using the widget factory. If a page exists at the given path, it is updated with the new widget spec (previous version saved for rollback). If no page exists, it is created. Use this instead of createReportPage when evolving an existing report.
Arguments:
path(string, required): URL path for the page (e.g. "/agent-report-my-space"). Must start with /, lowercase alphanumeric and hyphens only.title(string, required): Display title for the report pagedescription(string, optional): Optional subtitle displayed below the titletheme(string, optional): Color theme: "dark" (default) or "light"layout(string, optional): Layout: "dashboard" (2-col grid, default), "report" (single-col max-w-4xl), "single-column" (full-width single-col)visibility(string, optional): Page visibility: "private" (default) or "public"widgets(array, required): Array of widget specs. Each widget has: type (string), collection (Data collection slug — required for all types except text-block), transform (optional: { type:"raw"|"groupBy"|"timeSeries", ... }), display ({ title?, height? (number), colorIndex? }), config (type-specific fields — see below).
Widget types and their config fields:
- stat-grid: { columns: number, items: [{ label, valueField, format?, aggregate? }] }
- bar-chart: { xField, yField, orientation?, stacked? }
- line-chart: { xField, yFields: string[], smooth? }
- area-chart: { xField, yFields: string[], stacked? }
- pie-chart: { labelField, valueField, donut? }
- table: { columns: [{ field, label, format?, align? }], limit? }
- list: { titleField, subtitleField?, metaField?, limit? }
- metric-card: { valueField, label, format? }
- text-block: { content: string }
- treemap: { nameField, valueField }
- radar-chart: { axisField, valueFields: string[] }
Transform types:
- raw: { sort?: { field, direction }, limit? }
- groupBy: { field, metric: { field, op:
"sum"|"avg"|"count"|"min"|"max"}, sort?, limit? } - timeSeries: { timeField, granularity?:
"day"|"week"|"month"} updateReason(string, optional): Why the page is being updated (used as version description for rollback)
Returns:
object - Created or updated page with id, path, title, widgetCount, codeHash, action ("created" or "updated"), url
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
widgetCount | number | Number of widgets on the page |
codeHash | string | Hash of the compiled code |
action | 'created' | 'updated' | Whether the page was created or updated |
url | string | Public URL for the page |
visibility | string | Page visibility (present on create) (optional) |
accessInfo | string | Human-readable description of who can access the page |
lintWarnings | string | Lint warnings from code validation (optional) |
apiKey | string | API key for public pages (only shown once) (optional) |
Example:
editPage
Edit a page using search-and-replace. Each edit replaces one exact match of oldCode with newCode in the current source. Much more efficient than updatePage for small changes — only send the parts that change. Use getPage first to read the current code. The old_code string must appear exactly once in the source.
Arguments:
pageId(string, required): The page ID to editedits(array, required): Array of search-and-replace edits. Each edit has oldCode (exact string to find) and newCode (replacement string). Applied sequentially.
Returns:
object - Updated page with id, title, codeHash, versionsCount, appliedEdits count
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
codeHash | string | Hash of the compiled code |
versionsCount | number | Number of saved versions |
appliedEdits | number | Number of edits applied |
url | string | Public URL for the page |
lintWarnings | string | Lint warnings from code validation (optional) |
Example:
updatePage
Replace the entire page code. Use editPage instead for small changes — it is more efficient. Only use updatePage when rewriting most of the page.
Arguments:
pageId(string, required): The page ID to updatecode(string, optional): New page source, JSX or a self-contained HTML document. The format is detected automatically and may differ from the page's current one — replacing a JSX page with an artifact is a valid update.format(string, optional): Force the source format: "jsx" or "html". Normally omitted — see createPage.codePath(string, optional): Path to a source file in the workspace container. If provided, code is read from this file.title(string, optional): New titledescription(string, optional): New description
Returns:
object - Updated page with id, title, codeHash, versionsCount
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
description | string | Page description (optional) |
codeHash | string | Hash of the compiled code |
versionsCount | number | Number of saved versions |
url | string | Public URL for the page |
lintWarnings | string | Lint warnings from code validation (optional) |
Example:
revertPage
Revert a page to a previous version. The current code becomes a new version entry.
Arguments:
pageId(string, required): The page ID to revertversionIndex(number, required): Index of the version to restore (0 = most recent saved version)
Returns:
object - Reverted page with id, title, codeHash, versionsCount
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
codeHash | string | Hash of the compiled code |
versionsCount | number | Number of saved versions |
revertedFrom | number | Version index that was restored |
Example:
getPage
Get a page by its ID or by path within the current graph. Returns page metadata and current code.
Arguments:
pageId(string, optional): The page IDpath(string, optional): The page path (e.g. "/dashboard"). Used with the current graphId.
Returns:
object - Page with id, path, title, description, currentCode, visibility, versions, codeHash
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
description | string | Page description (optional) |
currentCode | string | Current JSX source code |
codeHash | string | Hash of the compiled code |
visibility | string | Page visibility: "private" or "public" |
widgetSpec | object | Widget specification if created via report page (optional) |
versions | object[] | Array of version history entries |
createdByUserId | string | User ID of the page creator |
lastEditedByUserId | string | User ID of the last editor |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
url | string | Public URL for the page |
Example:
listPages
List all pages for the current graph. Optionally filter by status.
Arguments:
status(string, optional): Filter by status: "active" (default) or "deleted"
Returns:
object - Array of pages with id, path, title, description, visibility, status, createdAt, updatedAt
Response Fields:
| Field | Type | Description |
|---|---|---|
pages | object[] | Array of page summary objects |
pages item fields (object)
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
description | string | Page description (optional) |
visibility | string | Page visibility: "private" or "public" |
status | string | Page status |
createdAt | string | Creation timestamp |
updatedAt | string | Last update timestamp |
url | string | Public URL for the page |
| count | number | Total number of pages returned |
Example:
deletePage
Soft-delete a page by setting its status to "deleted".
Arguments:
pageId(string, required): The page ID to delete
Returns:
object - Confirmation with page id and status
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
status | string | Page status (deleted) |
Example:
publishPage
Publish a page, making it publicly accessible. Generates an API key for the page.
Arguments:
pageId(string, required): The page ID to publishpublicCollections(array, optional): Optional array of collection tags for public discovery
Returns:
object - Published page with id, visibility, apiKey (only shown once), and url
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
visibility | string | Page visibility (public) |
url | string | Public URL for the page |
apiKey | string | API key (only shown once, only when newly generated) (optional) |
Example:
unpublishPage
Unpublish a page, making it private.
Arguments:
pageId(string, required): The page ID to unpublish
Returns:
object - Updated page with id and visibility
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
visibility | string | Page visibility (private) |
Example:
sharePage
Share a private page with another graph (group). Members of the target graph will be able to view the page after signing in. The page must belong to your current graph.
Arguments:
pageId(string, required): The page ID to sharegraphId(string, required): The graph ID (group ID) to share the page with
Returns:
object - Updated page with id, title, visibility, sharedWithGraphIds, and accessInfo
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
title | string | Display title of the page |
visibility | string | Page visibility |
sharedWithGraphIds | string[] | Graph IDs the page is shared with |
accessInfo | string | Human-readable access description |
Example:
shareToOrg
Share one of this space's pages with the whole organization. By default a page this space publishes is readable only inside this space, even though it is stored in the organization's namespace — sibling spaces cannot see it. Use this for the pages that genuinely are company-wide. There is no un-share op yet; treat it as a one-way decision.
Arguments:
pageId(string, required): The page ID to share with the organization
Returns:
object - Updated page with id, title, visibility, sharedWithGraphIds, and accessInfo
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
title | string | Display title of the page |
visibility | string | Page visibility |
sharedWithGraphIds | string[] | Graph IDs the page is shared with, now including the organization |
accessInfo | string | Human-readable access description |
Example:
getPageUrl
Get the public URL for a page.
Arguments:
pageId(string, required): The page ID
Returns:
object - Object with url string
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Page identifier |
path | string | URL path of the page |
url | string | Public URL for the page |
Example:
listFeedback
Read the comments teammates pinned onto one of your pages. A viewer clicks an element on the page and leaves a note attached to it, so each comment comes back with the text they wrote AND the part of the page they were pointing at — treat it as a specific change request, not general feedback.
Call this after you publish a page for review, and again before you edit a page someone has been commenting on. Comments default to open; resolveFeedback closes one once you have acted on it, so what comes back here is the work still outstanding.
A comment carries the codeHash of the page version it was left on. When stale is true the page has been edited since — the quoted element may have moved or gone, so re-read the page before assuming the comment still applies.
Arguments:
pageId(string, optional): The page ID. Get one from listPages or from the createPage result.path(string, optional): The page path instead of an ID (e.g. "/calendar-design-lab"), resolved within the current graph.status(string, optional): Which comments to return: "open" (default), "resolved", or "all".
Returns:
object - Page identity plus a comments array (text, who wrote it, what they pointed at, whether it is stale) and open/resolved counts
Response Fields:
| Field | Type | Description |
|---|---|---|
pageId | string | Page identifier |
path | string | URL path of the page |
title | string | Display title of the page |
url | string | Public URL for the page |
comments | object[] | Comments pinned onto the page, oldest first |
comments item fields (object)
| Field | Type | Description |
|---|---|---|
id | string | Comment identifier, used with resolveFeedback |
text | string | What the commenter wrote |
authorName | string | Display name of the commenter (optional) |
authorUserId | string | User ID of the commenter |
status | string | Comment status: "open" or "resolved" |
quotedText | string | Text of the page element the comment is pinned to (optional) |
selector | string | CSS selector of the element the comment is pinned to |
stale | boolean | True when the page has been edited since this comment was left, so the element it points at may have moved or gone |
createdAt | string | When the comment was left |
resolvedAt | string | When the comment was resolved, if it was (optional) |
| openCount | number | Number of open comments on the page |
| resolvedCount | number | Number of resolved comments on the page |
Example:
resolveFeedback
Close a page comment once you have acted on it, so it stops coming back from listFeedback. Resolve it when the change is actually made — not when you have read it. Pass status "open" to reopen one you closed too early.
Arguments:
feedbackId(string, required): The comment ID, from listFeedback.status(string, optional): "resolved" (default) or "open" to reopen.
Returns:
object - The comment with its new status and the page it belongs to
Response Fields:
| Field | Type | Description |
|---|---|---|
id | string | Comment identifier |
pageId | string | Page the comment belongs to |
status | string | New status: "open" or "resolved" |
text | string | What the commenter wrote |
openCount | number | Comments still open on the page after this change |
Example: