Skip to content

Commit f3bd986

Browse files
committed
Update to content-link 0.3.7 with stripStega support
- Update dependency to @datocms/content-link ^0.3.7 - ContentLink component: always pass stripStega: true and remove enabled prop - useContentLink hook: expose stripStega option via enabled parameter - enabled can now be: boolean | { stripStega: boolean } - true (default): preserves stega encoding - false: disables controller - { stripStega: true }: strips encoding for clean DOM - Update documentation to reflect new API
1 parent 957b494 commit f3bd986

File tree

5 files changed

+52
-16
lines changed

5 files changed

+52
-16
lines changed

docs/content-link.md

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -241,11 +241,10 @@ The `<ContentLink />` component accepts the following props:
241241

242242
| Prop | Type | Default | Description |
243243
| ------------------- | ---------------------------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
244-
| `enabled` | `boolean` | `true` | Whether the controller is enabled |
245244
| `onNavigateTo` | `(path: string) => void` | - | Callback when [Web Previews plugin](https://www.datocms.com/marketplace/plugins/i/datocms-plugin-web-previews) requests navigation to a different page |
246245
| `currentPath` | `string` | - | Current pathname to sync with [Web Previews plugin](https://www.datocms.com/marketplace/plugins/i/datocms-plugin-web-previews) |
247246
| `enableClickToEdit` | `true \| { scrollToNearestTarget: true }` | - | Enable click-to-edit overlays on mount. Pass `true` or an object with options. If undefined, click-to-edit is disabled |
248-
| `root` | `React.RefObject<ParentNode>` | - | Ref to limit scanning to this root element instead of the entire document |
247+
| `root` | `React.RefObject<HTMLElement>` | - | Ref to limit scanning to this root element instead of the entire document |
249248

250249
## Advanced usage: the `useContentLink` hook
251250

@@ -268,12 +267,27 @@ const {
268267
flashAll, // Highlight all editable elements
269268
setCurrentPath, // Notify Web Previews plugin of current path
270269
} = useContentLink({
270+
// enabled can be:
271+
// - true (default): Enable with default settings (stega encoding preserved)
272+
// - false: Disable the controller
273+
// - { stripStega: true }: Enable and strip stega encoding for clean DOM
271274
enabled: true,
272275
onNavigateTo: (path) => { /* handle navigation */ },
273276
root: elementRef,
274277
});
275278
```
276279

280+
**Options:**
281+
282+
- `enabled?: boolean | { stripStega: boolean }` - Controls whether the controller is enabled and how it handles stega encoding:
283+
- `true` (default): Enables the controller with stega encoding preserved in the DOM (allows controller recreation)
284+
- `false`: Disables the controller completely
285+
- `{ stripStega: true }`: Enables the controller and permanently removes stega encoding from text nodes for clean `textContent` access
286+
- `onNavigateTo?: (path: string) => void` - Callback when Web Previews plugin requests navigation
287+
- `root?: React.RefObject<HTMLElement>` - Ref to limit scanning to this root element
288+
289+
**Note:** The `<ContentLink />` component always uses `stripStega: true` for clean DOM output.
290+
277291
### Example: Custom editing toolbar
278292

279293
```jsx

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@
149149
"react": ">= 16.12.0 || ^19.0.0-rc"
150150
},
151151
"dependencies": {
152-
"@datocms/content-link": "^0.3.6",
152+
"@datocms/content-link": "^0.3.7",
153153
"@mux/mux-player-react": "*",
154154
"datocms-listen": "^0.1.9",
155155
"datocms-structured-text-generic-html-renderer": "^5.0.0",

src/ContentLink/index.tsx

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
useContentLink,
77
} from '../useContentLink/index.js';
88

9-
export type ContentLinkProps = UseContentLinkOptions & {
9+
export type ContentLinkProps = Omit<UseContentLinkOptions, 'enabled'> & {
1010
/** Current pathname to sync with Web Previews plugin */
1111
currentPath?: string;
1212
/** Enable click-to-edit on mount. Pass true for default behavior or an object with scrollToNearestTarget. If undefined, click-to-edit is disabled. */
@@ -84,9 +84,11 @@ export function ContentLink(props: ContentLinkProps): null {
8484
...useContentLinkOptions
8585
} = props;
8686

87-
const { enableClickToEdit, setCurrentPath } = useContentLink(
88-
useContentLinkOptions,
89-
);
87+
const { enableClickToEdit, setCurrentPath } = useContentLink({
88+
...useContentLinkOptions,
89+
// Always strip stega encoding in the component for clean DOM
90+
enabled: { stripStega: true },
91+
});
9092

9193
// Sync current path when it changes
9294
useEffect(() => {
@@ -95,7 +97,7 @@ export function ContentLink(props: ContentLinkProps): null {
9597
}
9698
}, [currentPath, setCurrentPath]);
9799

98-
// Optionally enable click-to-edit on mount
100+
// Enable click-to-edit on mount if requested
99101
useEffect(() => {
100102
if (enableClickToEditOptions !== undefined) {
101103
enableClickToEdit(

src/useContentLink/index.ts

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,25 @@ export type { Controller } from '@datocms/content-link';
88
export { decodeStega, stripStega } from '@datocms/content-link';
99

1010
export type UseContentLinkOptions = {
11-
/** Whether the controller is enabled (default: true) */
12-
enabled?: boolean;
11+
/**
12+
* Whether the controller is enabled, or an options object.
13+
* - Pass `true` (default): Enables the controller with stega encoding preserved (allows controller recreation)
14+
* - Pass `false`: Disables the controller completely
15+
* - Pass `{ stripStega: true }`: Enables the controller and strips stega encoding after stamping
16+
*
17+
* When stripStega is false (default): Stega encoding remains in the DOM, allowing controllers
18+
* to be disposed and recreated on the same page. The invisible characters don't affect display
19+
* but preserve the source of truth.
20+
*
21+
* When stripStega is true: Stega encoding is permanently removed from text nodes, providing
22+
* clean textContent for programmatic access. However, recreating a controller on the same page
23+
* won't detect elements since the encoding is lost.
24+
*/
25+
enabled?: boolean | { stripStega: boolean };
1326
/** Callback when Web Previews plugin requests navigation */
1427
onNavigateTo?: (path: string) => void;
1528
/** Ref to limit scanning to this root instead of document */
16-
root?: React.RefObject<ParentNode>;
29+
root?: React.RefObject<HTMLElement>;
1730
};
1831

1932
export type UseContentLinkResult = {
@@ -75,17 +88,24 @@ export function useContentLink(
7588
// Create/dispose controller based on enabled flag and root only
7689
// The onNavigateTo callback is accessed via ref, so changes don't trigger recreation
7790
useEffect(() => {
78-
if (!enabled) {
91+
// Check if controller is disabled
92+
const isEnabled = enabled === true || (typeof enabled === 'object' && enabled !== null);
93+
94+
if (!isEnabled) {
7995
if (controllerRef.current) {
8096
controllerRef.current.dispose();
8197
controllerRef.current = null;
8298
}
8399
return;
84100
}
85101

102+
// Extract stripStega option if enabled is an object
103+
const stripStega = typeof enabled === 'object' ? enabled.stripStega : false;
104+
86105
const controller = createController({
87106
onNavigateTo: (path: string) => onNavigateToRef.current?.(path),
88107
root: root?.current || undefined,
108+
stripStega,
89109
});
90110

91111
controllerRef.current = controller;

0 commit comments

Comments
 (0)