@payloadcms/plugin-seo 3.0.0-alpha.63 → 3.0.0-alpha.65

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAM5C,OAAO,KAAK,EAKV,YAAY,EACb,MAAM,YAAY,CAAA;AASnB,QAAA,MAAM,GAAG,iBACQ,YAAY,cAClB,MAAM,KAAG,MA8QjB,CAAA;AAEH,OAAO,EAAE,GAAG,EAAE,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAO5C,OAAO,KAAK,EAKV,YAAY,EACb,MAAM,YAAY,CAAA;AASnB,QAAA,MAAM,GAAG,iBACQ,YAAY,cAClB,MAAM,KAAG,MAkRjB,CAAA;AAEH,OAAO,EAAE,GAAG,EAAE,CAAA"}
package/dist/index.js CHANGED
@@ -1,3 +1,4 @@
1
+ import { addDataAndFileToRequest } from '@payloadcms/next/utilities';
1
2
  import { deepMerge } from 'payload/utilities';
2
3
  import React from 'react';
3
4
  import { MetaDescription } from './fields/MetaDescription.js';
@@ -155,7 +156,10 @@ const seo = (pluginConfig)=>(config)=>{
155
156
  ...config.endpoints ?? [],
156
157
  {
157
158
  handler: async (req)=>{
158
- const args = req.data;
159
+ const reqWithData = await addDataAndFileToRequest({
160
+ request: req
161
+ });
162
+ const args = reqWithData.data;
159
163
  const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : '';
160
164
  return new Response(JSON.stringify({
161
165
  result
@@ -168,7 +172,10 @@ const seo = (pluginConfig)=>(config)=>{
168
172
  },
169
173
  {
170
174
  handler: async (req)=>{
171
- const args = req.data;
175
+ const reqWithData = await addDataAndFileToRequest({
176
+ request: req
177
+ });
178
+ const args = reqWithData.data;
172
179
  const result = pluginConfig.generateDescription ? await pluginConfig.generateDescription(args) : '';
173
180
  return new Response(JSON.stringify({
174
181
  result
@@ -181,7 +188,10 @@ const seo = (pluginConfig)=>(config)=>{
181
188
  },
182
189
  {
183
190
  handler: async (req)=>{
184
- const args = req.data;
191
+ const reqWithData = await addDataAndFileToRequest({
192
+ request: req
193
+ });
194
+ const args = reqWithData.data;
185
195
  const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : '';
186
196
  return new Response(JSON.stringify({
187
197
  result
@@ -194,7 +204,10 @@ const seo = (pluginConfig)=>(config)=>{
194
204
  },
195
205
  {
196
206
  handler: async (req)=>{
197
- const args = req.data;
207
+ const reqWithData = await addDataAndFileToRequest({
208
+ request: req
209
+ });
210
+ const args = reqWithData.data;
198
211
  const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : '';
199
212
  return new Response(result, {
200
213
  status: 200
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import type { Config } from 'payload/config'\nimport type { Field, GroupField, TabsField, TextField } from 'payload/types'\n\nimport { deepMerge } from 'payload/utilities'\nimport React from 'react'\n\nimport type {\n GenerateDescription,\n GenerateImage,\n GenerateTitle,\n GenerateURL,\n PluginConfig,\n} from './types.js'\n\nimport { MetaDescription } from './fields/MetaDescription.js'\nimport { MetaImage } from './fields/MetaImage.js'\nimport { MetaTitle } from './fields/MetaTitle.js'\nimport { translations } from './translations/index.js'\nimport { Overview } from './ui/Overview.js'\nimport { Preview } from './ui/Preview.js'\n\nconst seo =\n (pluginConfig: PluginConfig) =>\n (config: Config): Config => {\n const seoFields: GroupField[] = [\n {\n name: 'meta',\n type: 'group',\n fields: [\n {\n name: 'overview',\n type: 'ui',\n admin: {\n components: {\n Field: Overview,\n },\n },\n label: 'Overview',\n },\n {\n name: 'title',\n type: 'text',\n admin: {\n components: {\n Field: (props) => (\n <MetaTitle\n {...props}\n hasGenerateTitleFn={typeof pluginConfig?.generateTitle === 'function'}\n />\n ),\n },\n },\n localized: true,\n ...((pluginConfig?.fieldOverrides?.title as unknown as TextField) ?? {}),\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n components: {\n Field: (props) => (\n <MetaDescription\n {...props}\n hasGenerateDescriptionFn={\n typeof pluginConfig?.generateDescription === 'function'\n }\n />\n ),\n },\n },\n localized: true,\n ...(pluginConfig?.fieldOverrides?.description ?? {}),\n },\n ...(pluginConfig?.uploadsCollection\n ? [\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n {\n name: 'image',\n type: 'upload',\n admin: {\n components: {\n Field: (props) => (\n <MetaImage\n {...props}\n hasGenerateImageFn={typeof pluginConfig?.generateImage === 'function'}\n />\n ),\n },\n description:\n 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',\n },\n label: 'Meta Image',\n localized: true,\n relationTo: pluginConfig?.uploadsCollection,\n ...(pluginConfig?.fieldOverrides?.image ?? {}),\n } as Field,\n ]\n : []),\n ...(pluginConfig?.fields || []),\n {\n name: 'preview',\n type: 'ui',\n admin: {\n components: {\n Field: (props) => (\n <Preview\n {...props}\n hasGenerateURLFn={typeof pluginConfig?.generateURL === 'function'}\n />\n ),\n },\n },\n label: 'Preview',\n },\n ],\n interfaceName: pluginConfig.interfaceName,\n label: 'SEO',\n },\n ]\n\n return {\n ...config,\n collections:\n config.collections?.map((collection) => {\n const { slug } = collection\n const isEnabled = pluginConfig?.collections?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n // prevent issues with auth enabled collections having an email field that shouldn't be moved to the SEO tab\n const emailField =\n (collection.auth ||\n !(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy)) &&\n collection.fields?.find((field) => 'name' in field && field.name === 'email')\n const hasOnlyEmailField = collection.fields?.length === 1 && emailField\n\n const seoTabs: TabsField[] = hasOnlyEmailField\n ? [\n {\n type: 'tabs',\n tabs: [\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n : [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this collection's base fields\n ...(collection?.fields?.[0]?.type === 'tabs' &&\n collection?.fields?.[0]?.tabs\n ? collection.fields[0].tabs\n : [\n {\n fields: [\n ...(emailField\n ? collection.fields.filter(\n (field) => 'name' in field && field.name !== 'email',\n )\n : collection.fields),\n ],\n label: collection?.labels?.singular || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...collection,\n fields: [\n ...(emailField ? [emailField] : []),\n ...seoTabs,\n ...(collection?.fields?.[0]?.type === 'tabs' ? collection.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...collection,\n fields: [...(collection?.fields || []), ...seoFields],\n }\n }\n\n return collection\n }) || [],\n endpoints: [\n ...(config.endpoints ?? []),\n {\n handler: async (req) => {\n const args: Parameters<GenerateTitle>[0] =\n req.data as unknown as Parameters<GenerateTitle>[0]\n const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-title',\n },\n {\n handler: async (req) => {\n const args: Parameters<GenerateDescription>[0] =\n req.data as unknown as Parameters<GenerateDescription>[0]\n const result = pluginConfig.generateDescription\n ? await pluginConfig.generateDescription(args)\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-description',\n },\n {\n handler: async (req) => {\n const args: Parameters<GenerateURL>[0] =\n req.data as unknown as Parameters<GenerateURL>[0]\n const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-url',\n },\n {\n handler: async (req) => {\n const args: Parameters<GenerateImage>[0] =\n req.data as unknown as Parameters<GenerateImage>[0]\n const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : ''\n return new Response(result, { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-image',\n },\n ],\n globals:\n config.globals?.map((global) => {\n const { slug } = global\n const isEnabled = pluginConfig?.globals?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n const seoTabs: TabsField[] = [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this global's base fields\n ...(global?.fields?.[0].type === 'tabs' && global?.fields?.[0].tabs\n ? global.fields[0].tabs\n : [\n {\n fields: [...(global?.fields || [])],\n label: global?.label || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...global,\n fields: [\n ...seoTabs,\n ...(global?.fields?.[0].type === 'tabs' ? global.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...global,\n fields: [...(global?.fields || []), ...seoFields],\n }\n }\n\n return global\n }) || [],\n i18n: {\n ...config.i18n,\n translations: {\n ...deepMerge(translations, config.i18n?.translations),\n },\n },\n }\n }\n\nexport { seo }\n"],"names":["deepMerge","React","MetaDescription","MetaImage","MetaTitle","translations","Overview","Preview","seo","pluginConfig","config","seoFields","name","type","fields","admin","components","Field","label","props","hasGenerateTitleFn","generateTitle","localized","fieldOverrides","title","hasGenerateDescriptionFn","generateDescription","description","uploadsCollection","hasGenerateImageFn","generateImage","relationTo","image","hasGenerateURLFn","generateURL","interfaceName","collections","map","collection","slug","isEnabled","includes","tabbedUI","emailField","auth","disableLocalStrategy","find","field","hasOnlyEmailField","length","seoTabs","tabs","filter","labels","singular","slice","endpoints","handler","req","args","data","result","Response","JSON","stringify","status","method","path","globals","global","i18n"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
1
+ {"version":3,"sources":["../src/index.tsx"],"sourcesContent":["import type { Config } from 'payload/config'\nimport type { Field, GroupField, TabsField, TextField } from 'payload/types'\n\nimport { addDataAndFileToRequest } from '@payloadcms/next/utilities'\nimport { deepMerge } from 'payload/utilities'\nimport React from 'react'\n\nimport type {\n GenerateDescription,\n GenerateImage,\n GenerateTitle,\n GenerateURL,\n PluginConfig,\n} from './types.js'\n\nimport { MetaDescription } from './fields/MetaDescription.js'\nimport { MetaImage } from './fields/MetaImage.js'\nimport { MetaTitle } from './fields/MetaTitle.js'\nimport { translations } from './translations/index.js'\nimport { Overview } from './ui/Overview.js'\nimport { Preview } from './ui/Preview.js'\n\nconst seo =\n (pluginConfig: PluginConfig) =>\n (config: Config): Config => {\n const seoFields: GroupField[] = [\n {\n name: 'meta',\n type: 'group',\n fields: [\n {\n name: 'overview',\n type: 'ui',\n admin: {\n components: {\n Field: Overview,\n },\n },\n label: 'Overview',\n },\n {\n name: 'title',\n type: 'text',\n admin: {\n components: {\n Field: (props) => (\n <MetaTitle\n {...props}\n hasGenerateTitleFn={typeof pluginConfig?.generateTitle === 'function'}\n />\n ),\n },\n },\n localized: true,\n ...((pluginConfig?.fieldOverrides?.title as unknown as TextField) ?? {}),\n },\n {\n name: 'description',\n type: 'textarea',\n admin: {\n components: {\n Field: (props) => (\n <MetaDescription\n {...props}\n hasGenerateDescriptionFn={\n typeof pluginConfig?.generateDescription === 'function'\n }\n />\n ),\n },\n },\n localized: true,\n ...(pluginConfig?.fieldOverrides?.description ?? {}),\n },\n ...(pluginConfig?.uploadsCollection\n ? [\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n {\n name: 'image',\n type: 'upload',\n admin: {\n components: {\n Field: (props) => (\n <MetaImage\n {...props}\n hasGenerateImageFn={typeof pluginConfig?.generateImage === 'function'}\n />\n ),\n },\n description:\n 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',\n },\n label: 'Meta Image',\n localized: true,\n relationTo: pluginConfig?.uploadsCollection,\n ...(pluginConfig?.fieldOverrides?.image ?? {}),\n } as Field,\n ]\n : []),\n ...(pluginConfig?.fields || []),\n {\n name: 'preview',\n type: 'ui',\n admin: {\n components: {\n Field: (props) => (\n <Preview\n {...props}\n hasGenerateURLFn={typeof pluginConfig?.generateURL === 'function'}\n />\n ),\n },\n },\n label: 'Preview',\n },\n ],\n interfaceName: pluginConfig.interfaceName,\n label: 'SEO',\n },\n ]\n\n return {\n ...config,\n collections:\n config.collections?.map((collection) => {\n const { slug } = collection\n const isEnabled = pluginConfig?.collections?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n // prevent issues with auth enabled collections having an email field that shouldn't be moved to the SEO tab\n const emailField =\n (collection.auth ||\n !(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy)) &&\n collection.fields?.find((field) => 'name' in field && field.name === 'email')\n const hasOnlyEmailField = collection.fields?.length === 1 && emailField\n\n const seoTabs: TabsField[] = hasOnlyEmailField\n ? [\n {\n type: 'tabs',\n tabs: [\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n : [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this collection's base fields\n ...(collection?.fields?.[0]?.type === 'tabs' &&\n collection?.fields?.[0]?.tabs\n ? collection.fields[0].tabs\n : [\n {\n fields: [\n ...(emailField\n ? collection.fields.filter(\n (field) => 'name' in field && field.name !== 'email',\n )\n : collection.fields),\n ],\n label: collection?.labels?.singular || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...collection,\n fields: [\n ...(emailField ? [emailField] : []),\n ...seoTabs,\n ...(collection?.fields?.[0]?.type === 'tabs' ? collection.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...collection,\n fields: [...(collection?.fields || []), ...seoFields],\n }\n }\n\n return collection\n }) || [],\n endpoints: [\n ...(config.endpoints ?? []),\n {\n handler: async (req) => {\n const reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateTitle>[0] =\n reqWithData.data as unknown as Parameters<GenerateTitle>[0]\n const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-title',\n },\n {\n handler: async (req) => {\n const reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateDescription>[0] =\n reqWithData.data as unknown as Parameters<GenerateDescription>[0]\n const result = pluginConfig.generateDescription\n ? await pluginConfig.generateDescription(args)\n : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-description',\n },\n {\n handler: async (req) => {\n const reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateURL>[0] =\n reqWithData.data as unknown as Parameters<GenerateURL>[0]\n const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : ''\n return new Response(JSON.stringify({ result }), { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-url',\n },\n {\n handler: async (req) => {\n const reqWithData = await addDataAndFileToRequest({ request: req })\n const args: Parameters<GenerateImage>[0] =\n reqWithData.data as unknown as Parameters<GenerateImage>[0]\n const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : ''\n return new Response(result, { status: 200 })\n },\n method: 'post',\n path: '/plugin-seo/generate-image',\n },\n ],\n globals:\n config.globals?.map((global) => {\n const { slug } = global\n const isEnabled = pluginConfig?.globals?.includes(slug)\n\n if (isEnabled) {\n if (pluginConfig?.tabbedUI) {\n const seoTabs: TabsField[] = [\n {\n type: 'tabs',\n tabs: [\n // append a new tab onto the end of the tabs array, if there is one at the first index\n // if needed, create a new `Content` tab in the first index for this global's base fields\n ...(global?.fields?.[0].type === 'tabs' && global?.fields?.[0].tabs\n ? global.fields[0].tabs\n : [\n {\n fields: [...(global?.fields || [])],\n label: global?.label || 'Content',\n },\n ]),\n {\n fields: seoFields,\n label: 'SEO',\n },\n ],\n },\n ]\n\n return {\n ...global,\n fields: [\n ...seoTabs,\n ...(global?.fields?.[0].type === 'tabs' ? global.fields.slice(1) : []),\n ],\n }\n }\n\n return {\n ...global,\n fields: [...(global?.fields || []), ...seoFields],\n }\n }\n\n return global\n }) || [],\n i18n: {\n ...config.i18n,\n translations: {\n ...deepMerge(translations, config.i18n?.translations),\n },\n },\n }\n }\n\nexport { seo }\n"],"names":["addDataAndFileToRequest","deepMerge","React","MetaDescription","MetaImage","MetaTitle","translations","Overview","Preview","seo","pluginConfig","config","seoFields","name","type","fields","admin","components","Field","label","props","hasGenerateTitleFn","generateTitle","localized","fieldOverrides","title","hasGenerateDescriptionFn","generateDescription","description","uploadsCollection","hasGenerateImageFn","generateImage","relationTo","image","hasGenerateURLFn","generateURL","interfaceName","collections","map","collection","slug","isEnabled","includes","tabbedUI","emailField","auth","disableLocalStrategy","find","field","hasOnlyEmailField","length","seoTabs","tabs","filter","labels","singular","slice","endpoints","handler","req","reqWithData","request","args","data","result","Response","JSON","stringify","status","method","path","globals","global","i18n"],"rangeMappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;","mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/plugin-seo",
3
- "version": "3.0.0-alpha.63",
3
+ "version": "3.0.0-alpha.65",
4
4
  "homepage:": "https://payloadcms.com",
5
5
  "repository": {
6
6
  "type": "git",
@@ -24,17 +24,18 @@
24
24
  "license": "MIT",
25
25
  "peerDependencies": {
26
26
  "react": "^18.0.0",
27
- "@payloadcms/translations": "3.0.0-alpha.63",
28
- "payload": "3.0.0-alpha.63",
29
- "@payloadcms/ui": "3.0.0-alpha.63"
27
+ "payload": "3.0.0-alpha.65",
28
+ "@payloadcms/ui": "3.0.0-alpha.65",
29
+ "@payloadcms/translations": "3.0.0-alpha.65"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@types/react": "18.2.74",
33
33
  "react": "^18.0.0",
34
+ "payload": "3.0.0-alpha.65",
34
35
  "@payloadcms/eslint-config": "1.1.1",
35
- "@payloadcms/translations": "3.0.0-alpha.63",
36
- "@payloadcms/ui": "3.0.0-alpha.63",
37
- "payload": "3.0.0-alpha.63"
36
+ "@payloadcms/translations": "3.0.0-alpha.65",
37
+ "@payloadcms/ui": "3.0.0-alpha.65",
38
+ "@payloadcms/next": "3.0.0-alpha.65"
38
39
  },
39
40
  "exports": {
40
41
  ".": {
package/src/index.tsx DELETED
@@ -1,296 +0,0 @@
1
- import type { Config } from 'payload/config'
2
- import type { Field, GroupField, TabsField, TextField } from 'payload/types'
3
-
4
- import { deepMerge } from 'payload/utilities'
5
- import React from 'react'
6
-
7
- import type {
8
- GenerateDescription,
9
- GenerateImage,
10
- GenerateTitle,
11
- GenerateURL,
12
- PluginConfig,
13
- } from './types.js'
14
-
15
- import { MetaDescription } from './fields/MetaDescription.js'
16
- import { MetaImage } from './fields/MetaImage.js'
17
- import { MetaTitle } from './fields/MetaTitle.js'
18
- import { translations } from './translations/index.js'
19
- import { Overview } from './ui/Overview.js'
20
- import { Preview } from './ui/Preview.js'
21
-
22
- const seo =
23
- (pluginConfig: PluginConfig) =>
24
- (config: Config): Config => {
25
- const seoFields: GroupField[] = [
26
- {
27
- name: 'meta',
28
- type: 'group',
29
- fields: [
30
- {
31
- name: 'overview',
32
- type: 'ui',
33
- admin: {
34
- components: {
35
- Field: Overview,
36
- },
37
- },
38
- label: 'Overview',
39
- },
40
- {
41
- name: 'title',
42
- type: 'text',
43
- admin: {
44
- components: {
45
- Field: (props) => (
46
- <MetaTitle
47
- {...props}
48
- hasGenerateTitleFn={typeof pluginConfig?.generateTitle === 'function'}
49
- />
50
- ),
51
- },
52
- },
53
- localized: true,
54
- ...((pluginConfig?.fieldOverrides?.title as unknown as TextField) ?? {}),
55
- },
56
- {
57
- name: 'description',
58
- type: 'textarea',
59
- admin: {
60
- components: {
61
- Field: (props) => (
62
- <MetaDescription
63
- {...props}
64
- hasGenerateDescriptionFn={
65
- typeof pluginConfig?.generateDescription === 'function'
66
- }
67
- />
68
- ),
69
- },
70
- },
71
- localized: true,
72
- ...(pluginConfig?.fieldOverrides?.description ?? {}),
73
- },
74
- ...(pluginConfig?.uploadsCollection
75
- ? [
76
- // eslint-disable-next-line @typescript-eslint/consistent-type-assertions
77
- {
78
- name: 'image',
79
- type: 'upload',
80
- admin: {
81
- components: {
82
- Field: (props) => (
83
- <MetaImage
84
- {...props}
85
- hasGenerateImageFn={typeof pluginConfig?.generateImage === 'function'}
86
- />
87
- ),
88
- },
89
- description:
90
- 'Maximum upload file size: 12MB. Recommended file size for images is <500KB.',
91
- },
92
- label: 'Meta Image',
93
- localized: true,
94
- relationTo: pluginConfig?.uploadsCollection,
95
- ...(pluginConfig?.fieldOverrides?.image ?? {}),
96
- } as Field,
97
- ]
98
- : []),
99
- ...(pluginConfig?.fields || []),
100
- {
101
- name: 'preview',
102
- type: 'ui',
103
- admin: {
104
- components: {
105
- Field: (props) => (
106
- <Preview
107
- {...props}
108
- hasGenerateURLFn={typeof pluginConfig?.generateURL === 'function'}
109
- />
110
- ),
111
- },
112
- },
113
- label: 'Preview',
114
- },
115
- ],
116
- interfaceName: pluginConfig.interfaceName,
117
- label: 'SEO',
118
- },
119
- ]
120
-
121
- return {
122
- ...config,
123
- collections:
124
- config.collections?.map((collection) => {
125
- const { slug } = collection
126
- const isEnabled = pluginConfig?.collections?.includes(slug)
127
-
128
- if (isEnabled) {
129
- if (pluginConfig?.tabbedUI) {
130
- // prevent issues with auth enabled collections having an email field that shouldn't be moved to the SEO tab
131
- const emailField =
132
- (collection.auth ||
133
- !(typeof collection.auth === 'object' && collection.auth.disableLocalStrategy)) &&
134
- collection.fields?.find((field) => 'name' in field && field.name === 'email')
135
- const hasOnlyEmailField = collection.fields?.length === 1 && emailField
136
-
137
- const seoTabs: TabsField[] = hasOnlyEmailField
138
- ? [
139
- {
140
- type: 'tabs',
141
- tabs: [
142
- {
143
- fields: seoFields,
144
- label: 'SEO',
145
- },
146
- ],
147
- },
148
- ]
149
- : [
150
- {
151
- type: 'tabs',
152
- tabs: [
153
- // append a new tab onto the end of the tabs array, if there is one at the first index
154
- // if needed, create a new `Content` tab in the first index for this collection's base fields
155
- ...(collection?.fields?.[0]?.type === 'tabs' &&
156
- collection?.fields?.[0]?.tabs
157
- ? collection.fields[0].tabs
158
- : [
159
- {
160
- fields: [
161
- ...(emailField
162
- ? collection.fields.filter(
163
- (field) => 'name' in field && field.name !== 'email',
164
- )
165
- : collection.fields),
166
- ],
167
- label: collection?.labels?.singular || 'Content',
168
- },
169
- ]),
170
- {
171
- fields: seoFields,
172
- label: 'SEO',
173
- },
174
- ],
175
- },
176
- ]
177
-
178
- return {
179
- ...collection,
180
- fields: [
181
- ...(emailField ? [emailField] : []),
182
- ...seoTabs,
183
- ...(collection?.fields?.[0]?.type === 'tabs' ? collection.fields.slice(1) : []),
184
- ],
185
- }
186
- }
187
-
188
- return {
189
- ...collection,
190
- fields: [...(collection?.fields || []), ...seoFields],
191
- }
192
- }
193
-
194
- return collection
195
- }) || [],
196
- endpoints: [
197
- ...(config.endpoints ?? []),
198
- {
199
- handler: async (req) => {
200
- const args: Parameters<GenerateTitle>[0] =
201
- req.data as unknown as Parameters<GenerateTitle>[0]
202
- const result = pluginConfig.generateTitle ? await pluginConfig.generateTitle(args) : ''
203
- return new Response(JSON.stringify({ result }), { status: 200 })
204
- },
205
- method: 'post',
206
- path: '/plugin-seo/generate-title',
207
- },
208
- {
209
- handler: async (req) => {
210
- const args: Parameters<GenerateDescription>[0] =
211
- req.data as unknown as Parameters<GenerateDescription>[0]
212
- const result = pluginConfig.generateDescription
213
- ? await pluginConfig.generateDescription(args)
214
- : ''
215
- return new Response(JSON.stringify({ result }), { status: 200 })
216
- },
217
- method: 'post',
218
- path: '/plugin-seo/generate-description',
219
- },
220
- {
221
- handler: async (req) => {
222
- const args: Parameters<GenerateURL>[0] =
223
- req.data as unknown as Parameters<GenerateURL>[0]
224
- const result = pluginConfig.generateURL ? await pluginConfig.generateURL(args) : ''
225
- return new Response(JSON.stringify({ result }), { status: 200 })
226
- },
227
- method: 'post',
228
- path: '/plugin-seo/generate-url',
229
- },
230
- {
231
- handler: async (req) => {
232
- const args: Parameters<GenerateImage>[0] =
233
- req.data as unknown as Parameters<GenerateImage>[0]
234
- const result = pluginConfig.generateImage ? await pluginConfig.generateImage(args) : ''
235
- return new Response(result, { status: 200 })
236
- },
237
- method: 'post',
238
- path: '/plugin-seo/generate-image',
239
- },
240
- ],
241
- globals:
242
- config.globals?.map((global) => {
243
- const { slug } = global
244
- const isEnabled = pluginConfig?.globals?.includes(slug)
245
-
246
- if (isEnabled) {
247
- if (pluginConfig?.tabbedUI) {
248
- const seoTabs: TabsField[] = [
249
- {
250
- type: 'tabs',
251
- tabs: [
252
- // append a new tab onto the end of the tabs array, if there is one at the first index
253
- // if needed, create a new `Content` tab in the first index for this global's base fields
254
- ...(global?.fields?.[0].type === 'tabs' && global?.fields?.[0].tabs
255
- ? global.fields[0].tabs
256
- : [
257
- {
258
- fields: [...(global?.fields || [])],
259
- label: global?.label || 'Content',
260
- },
261
- ]),
262
- {
263
- fields: seoFields,
264
- label: 'SEO',
265
- },
266
- ],
267
- },
268
- ]
269
-
270
- return {
271
- ...global,
272
- fields: [
273
- ...seoTabs,
274
- ...(global?.fields?.[0].type === 'tabs' ? global.fields.slice(1) : []),
275
- ],
276
- }
277
- }
278
-
279
- return {
280
- ...global,
281
- fields: [...(global?.fields || []), ...seoFields],
282
- }
283
- }
284
-
285
- return global
286
- }) || [],
287
- i18n: {
288
- ...config.i18n,
289
- translations: {
290
- ...deepMerge(translations, config.i18n?.translations),
291
- },
292
- },
293
- }
294
- }
295
-
296
- export { seo }