added SEO and nav

This commit is contained in:
briannelson95
2025-10-11 14:51:35 -04:00
parent 55859cf02a
commit ea3e216f62
10 changed files with 194 additions and 27 deletions

View File

@@ -7,6 +7,7 @@
"@payloadcms/db-postgres": "3.59.1",
"@payloadcms/next": "3.59.1",
"@payloadcms/payload-cloud": "3.59.1",
"@payloadcms/plugin-seo": "^3.59.1",
"@payloadcms/richtext-lexical": "3.59.1",
"@payloadcms/ui": "3.59.1",
"cross-env": "^7.0.3",
@@ -471,6 +472,8 @@
"@payloadcms/payload-cloud": ["@payloadcms/payload-cloud@3.59.1", "", { "dependencies": { "@aws-sdk/client-cognito-identity": "^3.614.0", "@aws-sdk/client-s3": "^3.614.0", "@aws-sdk/credential-providers": "^3.614.0", "@aws-sdk/lib-storage": "^3.614.0", "@payloadcms/email-nodemailer": "3.59.1", "amazon-cognito-identity-js": "^6.1.2", "nodemailer": "6.9.16" }, "peerDependencies": { "payload": "3.59.1" } }, "sha512-ZuP7ZPsu+GE4+07a1wrs/EaLQBhoA4Ij0en9YL+qHWAiLCPo8NF2L4cSdWrN+XKKA6G53gqLBaLotCJ8veR6uA=="],
"@payloadcms/plugin-seo": ["@payloadcms/plugin-seo@3.59.1", "", { "dependencies": { "@payloadcms/translations": "3.59.1", "@payloadcms/ui": "3.59.1" }, "peerDependencies": { "payload": "3.59.1", "react": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020", "react-dom": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020" } }, "sha512-Dc/tR/Vx+sprsY8lQhf/MdCasCY7B5ScTJfAgaYf00rQqY2Y1L8zFtg0tuwOIgtSXvRh/GbRS3+vZcPldagHIA=="],
"@payloadcms/richtext-lexical": ["@payloadcms/richtext-lexical@3.59.1", "", { "dependencies": { "@lexical/headless": "0.35.0", "@lexical/html": "0.35.0", "@lexical/link": "0.35.0", "@lexical/list": "0.35.0", "@lexical/mark": "0.35.0", "@lexical/react": "0.35.0", "@lexical/rich-text": "0.35.0", "@lexical/selection": "0.35.0", "@lexical/table": "0.35.0", "@lexical/utils": "0.35.0", "@payloadcms/translations": "3.59.1", "@payloadcms/ui": "3.59.1", "@types/uuid": "10.0.0", "acorn": "8.12.1", "bson-objectid": "2.0.4", "csstype": "3.1.3", "dequal": "2.0.3", "escape-html": "1.0.3", "jsox": "1.2.121", "lexical": "0.35.0", "mdast-util-from-markdown": "2.0.2", "mdast-util-mdx-jsx": "3.1.3", "micromark-extension-mdx-jsx": "3.0.1", "qs-esm": "7.0.2", "react-error-boundary": "4.1.2", "ts-essentials": "10.0.3", "uuid": "10.0.0" }, "peerDependencies": { "@faceless-ui/modal": "3.0.0", "@faceless-ui/scroll-info": "2.0.0", "@payloadcms/next": "3.59.1", "payload": "3.59.1", "react": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020", "react-dom": "^19.0.0 || ^19.0.0-rc-65a56d0e-20241020" } }, "sha512-bVuLAnOxR1kL8IYD5iD269eO47ptX9/dxR2mFbJCYyG5qWFSU9gH3ocgJc/vVcU4SmghFADIxQzrpinPYmtveQ=="],
"@payloadcms/translations": ["@payloadcms/translations@3.59.1", "", { "dependencies": { "date-fns": "4.1.0" } }, "sha512-kBuYV4tGOUpVkh6es6cBhbJn14dGtNnYkGtHhScbtGVX6ZJyVudY9ypKQhljAEzdQq0n+kkmi1sfwlaRps+t6w=="],

View File

@@ -22,6 +22,7 @@
"@payloadcms/db-postgres": "3.59.1",
"@payloadcms/next": "3.59.1",
"@payloadcms/payload-cloud": "3.59.1",
"@payloadcms/plugin-seo": "^3.59.1",
"@payloadcms/richtext-lexical": "3.59.1",
"@payloadcms/ui": "3.59.1",
"cross-env": "^7.0.3",

View File

@@ -22,6 +22,11 @@ import { StrikethroughFeatureClient as StrikethroughFeatureClient_e70f5e05f09f93
import { UnderlineFeatureClient as UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { BoldFeatureClient as BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { ItalicFeatureClient as ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864 } from '@payloadcms/richtext-lexical/client'
import { OverviewComponent as OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { MetaTitleComponent as MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { MetaImageComponent as MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { MetaDescriptionComponent as MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { PreviewComponent as PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860 } from '@payloadcms/plugin-seo/client'
import { SlugField as SlugField_3817bf644402e67bfe6577f60ef982de } from '@payloadcms/ui'
export const importMap = {
@@ -49,5 +54,10 @@ export const importMap = {
"@payloadcms/richtext-lexical/client#UnderlineFeatureClient": UnderlineFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#BoldFeatureClient": BoldFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/richtext-lexical/client#ItalicFeatureClient": ItalicFeatureClient_e70f5e05f09f93e00b997edb1ef0c864,
"@payloadcms/plugin-seo/client#OverviewComponent": OverviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#MetaTitleComponent": MetaTitleComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#MetaImageComponent": MetaImageComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#MetaDescriptionComponent": MetaDescriptionComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/plugin-seo/client#PreviewComponent": PreviewComponent_a8a977ebc872c5d5ea7ee689724c0860,
"@payloadcms/ui#SlugField": SlugField_3817bf644402e67bfe6577f60ef982de
}

View File

@@ -0,0 +1,22 @@
import { GlobalConfig } from 'payload';
export const Nav: GlobalConfig = {
slug: 'nav',
label: 'Navigation',
fields: [
{
name: 'items',
type: 'array',
required: true,
maxRows: 8,
fields: [
{
name: 'page',
type: 'relationship',
relationTo: 'pages',
required: true,
}
]
}
]
}

View File

@@ -1,3 +1,4 @@
import { MetaDescriptionField, MetaImageField, MetaTitleField, OverviewField, PreviewField } from '@payloadcms/plugin-seo/fields'
import type { CollectionConfig } from 'payload'
import { slugField } from 'payload'
@@ -16,10 +17,49 @@ export const Page: CollectionConfig = {
type: 'text',
required: true,
},
{
type: 'tabs',
tabs: [
{
label: 'Content',
fields: [
{
name: 'richText',
type: 'richText'
},
]
},
{
name: 'meta',
label: 'SEO',
fields: [
OverviewField({
titlePath: 'meta.title',
descriptionPath: 'meta.description',
imagePath: 'meta.image',
}),
MetaTitleField({
hasGenerateFn: true,
}),
MetaImageField({
relationTo: 'media',
}),
MetaDescriptionField({}),
PreviewField({
// if the `generateUrl` function is configured
hasGenerateFn: true,
// field paths to match the target field for data
titlePath: 'meta.title',
descriptionPath: 'meta.description',
}),
],
},
]
},
slugField(),
],
}

View File

@@ -1,6 +1,5 @@
import type { CollectionConfig } from 'payload'
import { slugField } from 'payload'
import { fa } from 'payload/i18n/fa'
export const Projects: CollectionConfig = {
slug: 'projects',
@@ -72,7 +71,7 @@ export const Projects: CollectionConfig = {
{
name: 'order',
type: 'number',
defaultValue: 0,
defaultValue: undefined,
admin: {
position: 'sidebar'
}

View File

@@ -0,0 +1,8 @@
import type { CollectionConfig } from 'payload';
export const Settings: CollectionConfig = {
slug: 'settings',
fields: [
]
}

View File

@@ -90,8 +90,12 @@ export interface Config {
db: {
defaultIDType: number;
};
globals: {};
globalsSelect: {};
globals: {
nav: Nav;
};
globalsSelect: {
nav: NavSelect<false> | NavSelect<true>;
};
locale: null;
user: User & {
collection: 'users';
@@ -141,6 +145,14 @@ export interface Page {
};
[k: string]: unknown;
} | null;
meta?: {
title?: string | null;
/**
* Maximum upload file size: 12MB. Recommended file size for images is <500KB.
*/
image?: (number | null) | Media;
description?: string | null;
};
/**
* When enabled, the slug will auto-generate from the title field on save and autosave.
*/
@@ -149,6 +161,25 @@ export interface Page {
updatedAt: string;
createdAt: string;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "media".
*/
export interface Media {
id: number;
alt: string;
updatedAt: string;
createdAt: string;
url?: string | null;
thumbnailURL?: string | null;
filename?: string | null;
mimeType?: string | null;
filesize?: number | null;
width?: number | null;
height?: number | null;
focalX?: number | null;
focalY?: number | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "projects".
@@ -226,25 +257,6 @@ export interface User {
| null;
password?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "media".
*/
export interface Media {
id: number;
alt: string;
updatedAt: string;
createdAt: string;
url?: string | null;
thumbnailURL?: string | null;
filename?: string | null;
mimeType?: string | null;
filesize?: number | null;
width?: number | null;
height?: number | null;
focalX?: number | null;
focalY?: number | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "payload-locked-documents".
@@ -321,6 +333,13 @@ export interface PayloadMigration {
export interface PagesSelect<T extends boolean = true> {
title?: T;
richText?: T;
meta?:
| T
| {
title?: T;
image?: T;
description?: T;
};
generateSlug?: T;
slug?: T;
updatedAt?: T;
@@ -429,6 +448,34 @@ export interface PayloadMigrationsSelect<T extends boolean = true> {
updatedAt?: T;
createdAt?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "nav".
*/
export interface Nav {
id: number;
items: {
page: number | Page;
id?: string | null;
}[];
updatedAt?: string | null;
createdAt?: string | null;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "nav_select".
*/
export interface NavSelect<T extends boolean = true> {
items?:
| T
| {
page?: T;
id?: T;
};
updatedAt?: T;
createdAt?: T;
globalType?: T;
}
/**
* This interface was referenced by `Config`'s JSON-Schema
* via the `definition` "auth".

View File

@@ -12,6 +12,10 @@ import { Media } from './collections/Media'
import { Page } from './collections/Page'
import { Projects } from './collections/Projects'
import { Categories } from './collections/Categories'
import { Nav } from './collections/Nav'
import { seoPlugin } from '@payloadcms/plugin-seo'
import { GenerateTitle, GenerateURL } from '@payloadcms/plugin-seo/types'
import { plugins } from './plugins'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@@ -23,7 +27,16 @@ export default buildConfig({
baseDir: path.resolve(dirname),
},
},
collections: [Page, Projects, Categories, Users, Media],
collections: [
Page,
Projects,
Categories,
Users,
Media,
],
globals: [
Nav,
],
editor: lexicalEditor({
features: ({ defaultFeatures, rootFeatures }) => [
...defaultFeatures,
@@ -62,7 +75,7 @@ export default buildConfig({
}),
sharp,
plugins: [
payloadCloudPlugin(),
...plugins
// storage-adapter-placeholder
],
})

24
src/plugins/index.ts Normal file
View File

@@ -0,0 +1,24 @@
import { payloadCloudPlugin } from "@payloadcms/payload-cloud";
import { seoPlugin } from "@payloadcms/plugin-seo";
import { GenerateTitle, GenerateURL } from "@payloadcms/plugin-seo/types";
import { Plugin } from "payload";
import { Page, Project } from "../payload-types";
import { getServerSideURL } from "@/utilities/getURL";
const generateTitle: GenerateTitle<Project | Page> = ({ doc }) => {
return doc?.title ? `${doc.title} | Payload Website Template` : 'Payload Website Template'
}
const generateURL: GenerateURL<Project | Page> = ({ doc }) => {
const url = getServerSideURL()
return doc?.slug ? `${url}/${doc.slug}` : url
}
export const plugins: Plugin[] = [
payloadCloudPlugin(),
seoPlugin({
generateTitle,
generateURL,
}),
]