Service for adding interactive features to content rendered from the Lynkow API.

Accessible via lynkow.enhancements. This is a browser-only service: all methods are no-ops on the server. Currently provides:

  • Copy button for code blocks (elements with [data-copy-code] attribute)

  • Script activation for inline scripts injected via dangerouslySetInnerHTML

  • Widget iframe auto-resize for embedded Lynkow widgets

  • CSS normalization to ensure content renders correctly with CSS frameworks (Tailwind, etc.)

A MutationObserver automatically detects new content added to the DOM and applies enhancements, making it compatible with SPA frameworks like React/Next.js. Script clones are appended to <head> (not inline) to avoid React DOM reconciliation issues.

Code-block theming

Code-block CSS is driven by CSS custom properties (--lynkow-code-bg, --lynkow-code-fg, --lynkow-code-border, --lynkow-code-muted-fg, --lynkow-code-copy-fg-hover, --lynkow-code-copy-bg-hover). The light variant is triggered by any of the common theming conventions on <html>, <body> or the .code-block element itself: .light class, data-theme~="light", data-mode~="light", data-color-scheme~="light". prefers-color-scheme: light is kept as an OS-level fallback that only applies when no explicit dark signal is present on <html>. Override any variable in your own stylesheet to customise without !important.

Pass init({ codeBlocks: false }) if you handle code-block rendering yourself; the SDK will skip code-block CSS injection and copy-button binding.

Access via: lynkow.enhancements

Methods

3 methods

destroy

TypeScript
destroy(): void

Clean up every resource the enhancements service owns: disconnect the MutationObserver, remove the widget resize listener, cancel any pending animation frame, remove injected styles and cloned scripts from <head>, and reset the initialized state. Safe to call repeatedly; subsequent calls are no-ops. After destroy() you can re-attach by calling init() again. No-op on server.

Returns: void

TypeScript
useEffect(() => {
  lynkow.enhancements.init()
  return () => lynkow.enhancements.destroy()
}, [])

init

TypeScript
init(options: EnhancementsInitOptions): void

Initializes content enhancements: injects CSS styles, binds copy-to-clipboard handlers on code blocks, activates inline scripts, starts the widget iframe resize listener, and sets up a MutationObserver to automatically enhance newly added DOM content. Idempotent: calling multiple times has no effect after the first initialization. No-op on server.

Call this manually if you need to re-initialize after the client is created (e.g. after dynamically loading content outside the initial render).

Parameter

Type

Description

options

EnhancementsInitOptions

Optional behavior toggles. See EnhancementsInitOptions.<br> Pass { codeBlocks: false } to skip code-block CSS injection and the copy<br> button binding (useful when your renderer already handles code blocks).

Returns: void

TypeScript
// Default: inject everything.
lynkow.enhancements.init()

// Reinitialize enhancements after dynamically loading new content.
const html = await fetchArticleContent()
document.getElementById('article').innerHTML = html
lynkow.enhancements.init()

// Opt out of code-block styling when using your own highlighter (Shiki, Prism, ...).
lynkow.enhancements.init({ codeBlocks: false })

isInitialized

TypeScript
isInitialized(): boolean

Check whether the enhancements service has been initialized for the current page. Returns false on the server and after a call to destroy (until init() is invoked again).

Returns: boolean

TypeScript
if (!lynkow.enhancements.isInitialized()) {
  lynkow.enhancements.init()
}