@@ -10,6 +10,7 @@ import type {
10
10
import escapeHTML from 'escape-html'
11
11
import { sanitizeFields } from 'payload'
12
12
13
+ import type { NodeWithHooks } from '../../typesServer.js'
13
14
import type { ClientProps } from '../client/index.js'
14
15
15
16
import { createServerFeature } from '../../../utilities/createServerFeature.js'
@@ -46,6 +47,16 @@ export type ExclusiveLinkCollectionsProps =
46
47
}
47
48
48
49
export type LinkFeatureServerProps = {
50
+ /**
51
+ * Disables the automatic creation of links from URLs pasted into the editor, as well
52
+ * as auto link nodes.
53
+ *
54
+ * If set to 'creationOnly', only the creation of new auto link nodes will be disabled.
55
+ * Existing auto link nodes will still be editable.
56
+ *
57
+ * @default false
58
+ */
59
+ disableAutoLinks ?: 'creationOnly' | true
49
60
/**
50
61
* A function or array defining additional fields for the link feature. These will be
51
62
* displayed in the link editor drawer.
@@ -130,6 +141,7 @@ export const LinkFeature = createServerFeature<
130
141
clientFeatureProps : {
131
142
defaultLinkType,
132
143
defaultLinkURL,
144
+ disableAutoLinks : props . disableAutoLinks ,
133
145
disabledCollections : props . disabledCollections ,
134
146
enabledCollections : props . enabledCollections ,
135
147
} as ClientProps ,
@@ -148,55 +160,57 @@ export const LinkFeature = createServerFeature<
148
160
i18n,
149
161
markdownTransformers : [ LinkMarkdownTransformer ] ,
150
162
nodes : [
151
- createNode ( {
152
- converters : {
153
- html : {
154
- converter : async ( {
155
- converters,
156
- currentDepth,
157
- depth,
158
- draft,
159
- node,
160
- overrideAccess,
161
- parent,
162
- req,
163
- showHiddenFields,
164
- } ) => {
165
- const childrenText = await convertLexicalNodesToHTML ( {
166
- converters,
167
- currentDepth,
168
- depth,
169
- draft,
170
- lexicalNodes : node . children ,
171
- overrideAccess,
172
- parent : {
173
- ...node ,
163
+ props ?. disableAutoLinks === true
164
+ ? null
165
+ : createNode ( {
166
+ converters : {
167
+ html : {
168
+ converter : async ( {
169
+ converters,
170
+ currentDepth,
171
+ depth,
172
+ draft,
173
+ node,
174
+ overrideAccess,
174
175
parent,
175
- } ,
176
- req,
177
- showHiddenFields,
178
- } )
176
+ req,
177
+ showHiddenFields,
178
+ } ) => {
179
+ const childrenText = await convertLexicalNodesToHTML ( {
180
+ converters,
181
+ currentDepth,
182
+ depth,
183
+ draft,
184
+ lexicalNodes : node . children ,
185
+ overrideAccess,
186
+ parent : {
187
+ ...node ,
188
+ parent,
189
+ } ,
190
+ req,
191
+ showHiddenFields,
192
+ } )
179
193
180
- const rel : string = node . fields . newTab ? ' rel="noopener noreferrer"' : ''
181
- const target : string = node . fields . newTab ? ' target="_blank"' : ''
194
+ const rel : string = node . fields . newTab ? ' rel="noopener noreferrer"' : ''
195
+ const target : string = node . fields . newTab ? ' target="_blank"' : ''
182
196
183
- let href : string = node . fields . url ?? ''
184
- if ( node . fields . linkType === 'internal' ) {
185
- href =
186
- typeof node . fields . doc ?. value !== 'object'
187
- ? String ( node . fields . doc ?. value )
188
- : String ( node . fields . doc ?. value ?. id )
189
- }
197
+ let href : string = node . fields . url ?? ''
198
+ if ( node . fields . linkType === 'internal' ) {
199
+ href =
200
+ typeof node . fields . doc ?. value !== 'object'
201
+ ? String ( node . fields . doc ?. value )
202
+ : String ( node . fields . doc ?. value ?. id )
203
+ }
190
204
191
- return `<a href="${ href } "${ target } ${ rel } >${ childrenText } </a>`
205
+ return `<a href="${ href } "${ target } ${ rel } >${ childrenText } </a>`
206
+ } ,
207
+ nodeTypes : [ AutoLinkNode . getType ( ) ] ,
208
+ } ,
192
209
} ,
193
- nodeTypes : [ AutoLinkNode . getType ( ) ] ,
194
- } ,
195
- } ,
196
- node : AutoLinkNode ,
197
- // Since AutoLinkNodes are just internal links, they need no hooks or graphQL population promises
198
- validations : [ linkValidation ( props , sanitizedFieldsWithoutText ) ] ,
199
- } ) ,
210
+ node : AutoLinkNode ,
211
+ // Since AutoLinkNodes are just internal links, they need no hooks or graphQL population promises
212
+ validations : [ linkValidation ( props , sanitizedFieldsWithoutText ) ] ,
213
+ } ) ,
200
214
createNode ( {
201
215
converters : {
202
216
html : {
@@ -249,7 +263,7 @@ export const LinkFeature = createServerFeature<
249
263
node : LinkNode ,
250
264
validations : [ linkValidation ( props , sanitizedFieldsWithoutText ) ] ,
251
265
} ) ,
252
- ] ,
266
+ ] . filter ( Boolean ) as Array < NodeWithHooks > ,
253
267
sanitizedServerFeatureProps : props ,
254
268
}
255
269
} ,
0 commit comments