Skip to content

Improve README clarity for Umbraco JSON output, performance, and style filtering#29

Draft
Copilot wants to merge 11 commits into
mainfrom
copilot/improve-readme-clarity
Draft

Improve README clarity for Umbraco JSON output, performance, and style filtering#29
Copilot wants to merge 11 commits into
mainfrom
copilot/improve-readme-clarity

Conversation

Copilot AI commented Dec 23, 2025

Copy link
Copy Markdown
Contributor

Updated documentation to clarify enabling Umbraco Content Delivery API JSON output and add guidance for performant rich text rendering and selective inline style handling.

  • Content Delivery API setup

    • Added appsettings.json snippet showing RichTextOutputAsJson: true.
  • Rendering performance and memoization

    • Emphasized server-side rendering preference and stable renderNode/renderBlock usage with useCallback/useMemo where appropriate.
  • Referenced content handling

    • Documented fetching/caching strategies for linked nodes (server-side hydration, batching, Suspense fallback).
  • Selective inline style filtering

    • Introduced helper to keep only allowed CSS properties without mutating original attributes.

Example (style filtering):

import { createElement } from "react";

const ALLOWED_STYLES = ["font-weight", "font-style"];

function filterAllowedStyles(style: string) {
  const allowed: string[] = [];
  for (const rule of style.split(";")) {
    const [property, ...rest] = rule.split(":");
    const name = property?.trim();
    const value = rest.join(":").trim();
    if (name && value && ALLOWED_STYLES.includes(name)) allowed.push(`${name}: ${value}`);
  }
  return allowed.length ? allowed.join("; ") : undefined;
}

function renderNode({ tag, attributes, children }: RenderNodeContext) {
  if (typeof attributes.style === "string") {
    const filtered = filterAllowedStyles(attributes.style);
    const next = { ...attributes };
    if (filtered) next.style = filtered;
    else delete next.style;
    return createElement(tag, next, children);
  }
  return undefined;
}

Warning

Firewall rules blocked me from connecting to one or more addresses (expand for details)

I tried to connect to the following addresses, but was blocked by firewall rules:

  • diversa-dk.euwest01.umbraco.io
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutoDeElevate,RenderD k/umbraco-rich-text/umbraco-rich-text/node_modules/.bin/ldd ubuntu2_amd64.deldd %3a6.1.1-3ubuntu/home/REDACTED/.cache/ms-playwright/webkit-2227/minibrowser-wpe/sys/lib/libsoup-3.0.so.0.7.4 /usr/bin/apt-config rm (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutoDeElevate,RenderD x86-64.so.2 eta20-4build2_amsort (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutoDeElevate,RenderD /usr/local/sbin/ldd 1build1_amd64.decat p.ci plit ldd (dns block)
  • esm.ubuntu.com
    • Triggering command: /usr/lib/apt/methods/https /usr/lib/apt/methods/https (dns block)
  • https://storage.googleapis.com/chrome-for-testing-public/143.0.7499.4/linux64/chrome-headless-shell-linux64.zip
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/umbraco-rich-text/umbraco-rich-text/node_modules/.pnpm/playwright-core@1.57.0/node_modules/playwright-core/lib/server/registry/oopDownloadBrowserMain.js (http block)
  • https://storage.googleapis.com/chrome-for-testing-public/143.0.7499.4/linux64/chrome-linux64.zip
    • Triggering command: /usr/local/bin/node /usr/local/bin/node /home/REDACTED/work/umbraco-rich-text/umbraco-rich-text/node_modules/.pnpm/playwright-core@1.57.0/node_modules/playwright-core/lib/server/registry/oopDownloadBrowserMain.js es/.pnpm/@esbuil-- dpkg-deb --fs�� 1-3build1_amd64.deb p.ci plit (http block)
  • images.unsplash.com
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutoDeElevate,RenderD k/umbraco-rich-text/umbraco-rich-text/node_modules/.bin/ldd ubuntu2_amd64.deldd %3a6.1.1-3ubuntu/home/REDACTED/.cache/ms-playwright/webkit-2227/minibrowser-wpe/sys/lib/libsoup-3.0.so.0.7.4 /usr/bin/apt-config rm (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutoDeElevate,RenderD x86-64.so.2 eta20-4build2_amsort (dns block)
    • Triggering command: /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell /home/REDACTED/.cache/ms-playwright/chromium_headless_shell-1200/chrome-headless-shell-linux64/chrome-headless-shell --disable-field-trial-config --disable-REDACTED-networking --disable-REDACTED-timer-throttling --disable-REDACTEDing-occluded-windows --disable-back-forward-cache --disable-breakpad --disable-client-side-phishing-detection --disable-component-extensions-with-REDACTED-pages --disable-component-update --no-default-browser-check --disable-default-apps --disable-dev-shm-usage --disable-extensions --disable-features=AcceptCHFrame,AvoidUnnecessaryBeforeUnloadCheckSync,DestroyProfileOnBrowserClose,DialMediaRouteProvider,GlobalMediaControls,HttpsUpgrades,LensOverlay,MediaRouter,PaintHolding,ThirdPartyStoragePartitioning,Translate,AutoDeElevate,RenderD /usr/local/sbin/ldd 1build1_amd64.decat p.ci plit ldd (dns block)

If you need me to access, download, or install something from one of these locations, you can either:

Original prompt

This section details on the original issue you should resolve

<issue_title>Context 7 rating</issue_title>
<issue_description>Context7 has asked questions about the framework, and rated the answers based on the readme. Can we improve the readme, so it becomes clearer?

https://context7.vercel.app/charlie-tango/umbraco-rich-text?tab=benchmark

Question 1
How would you render a rich text field from Umbraco's Content Delivery API using the UmbracoRichText component, and what prop is required to enable JSON output from the API?

Score: 66

Explanation
The context is highly effective for explaining how to render rich text using the UmbracoRichText component, but completely fails to address how to configure Umbraco's Content Delivery API for JSON output. The strongest aspect is the comprehensive and diverse set of code examples for rendering rich text, including custom node/block renderers, styling, and prop usage, making it easy to understand component implementation. A critical missing element is any information regarding the Umbraco Content Delivery API itself, specifically the "prop" or configuration needed to ensure rich text is returned in a JSON format suitable for the component. It scored 24/40 for implementation guidance, 23/25 for API accuracy, 10/20 for relevance to the question, 4/10 for completeness, and 5/5 for clarity and usability.

Question 2
Write a code example demonstrating how to use the renderNode prop to customize the rendering of heading nodes while allowing other nodes to use default rendering.

Score: 92

Explanation
The context provides exceptionally clear and comprehensive guidance for implementing custom heading node rendering with fallback to defaults, directly addressing the question through multiple working examples that demonstrate the exact pattern needed. The strongest aspect is the consistent demonstration across multiple code snippets showing how to return undefined from renderNode to trigger default rendering, combined with the API documentation that explicitly explains this behavior. The documentation is well-organized with clear examples progressing from basic to advanced patterns, though it lacks explicit edge case handling for malformed heading data or specific warnings about performance implications with complex custom renderers. The scoring reflects: Implementation Guidance (38/40) - excellent working examples with clear patterns, API Accuracy (25/25) - current and correct usage, Relevance (20/20) - directly addresses the question, Completeness (8/10) - missing error handling examples, and Clarity (5/5) - well-organized with explanations.

Question 5
How would you implement a custom block renderer that accesses metadata about ancestor and sibling elements using the meta() function?

Score: 78

Explanation
The documentation context effectively demonstrates custom block rendering with the meta() function shown in multiple examples, particularly in the 'Render Umbraco Rich Text with Custom Node and Block Rendering in React' section which directly illustrates accessing ancestor/sibling metadata through meta() to determine if a paragraph is first. The strongest aspect is the comprehensive, production-ready code examples showing RenderNodeContext and RenderBlockContext usage with proper TypeScript typing and real-world scenarios like conditional styling based on node position. However, the context lacks explicit documentation explaining what the meta() function returns, what metadata fields are available (beyond the previous property shown), and how to access sibling or ancestor information comprehensively, leaving some implementation details unclear. The scoring reflects strong implementation guidance (38/40) and excellent API accuracy (24/25), but moderate relevance (16/20) since the question specifically asks about 'ancestor and sibling elements' while examples only demonstrate basic previous-node detection, good completeness (9/10) with minor gaps in metadata API details, and clear organization (5/5).

NOTE: The readme has already been updated with an example of using metadata, so this score is outdated.

Question 7
How can you prevent unnecessary re-renders when defining custom renderNode and renderBlock functions, and why is this important?

Score: 18

Explanation
The context fails to address the core question about preventing unnecessary re-renders in renderNode and renderBlock functions, providing no memoization strategies, useCallback patterns, or discussion of React performance optimization techniques. While the code examples demonstrate correct API usage with proper imports and comprehensive feature coverage including custom renderers, style stripping, and TypeScript typing, this foundational knowledge is irrelevant to the specific implementation challenge posed. The documentation completely omits critical optimization patterns such as wrapping renderers in useCallback, extracting functions ...

  • Fixes charlie-tango/umbraco-rich-text#28

✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.

Copilot AI and others added 10 commits December 23, 2025 15:46
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Co-authored-by: thebuilder <3764345+thebuilder@users.noreply.github.com>
Copilot AI changed the title [WIP] Improve clarity of readme for UmbracoRichText component Improve README clarity for Umbraco JSON output, performance, and style filtering Dec 23, 2025
Copilot AI requested a review from thebuilder December 23, 2025 16:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants