chore(templates): adds getURL util to website & with-vercel-website templates (#9336)

This commit is contained in:
Patrik
2024-11-19 14:43:22 -05:00
committed by GitHub
parent 9ea26638e9
commit 1dc8094905
30 changed files with 120 additions and 42 deletions

View File

@@ -15,6 +15,7 @@ import { mergeOpenGraph } from '@/utilities/mergeOpenGraph'
import { draftMode } from 'next/headers'
import './globals.css'
import { getServerSideURL } from '@/utilities/getURL'
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const { isEnabled } = await draftMode()
@@ -45,7 +46,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
}
export const metadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_SERVER_URL || 'https://payloadcms.com'),
metadataBase: new URL(getServerSideURL()),
openGraph: mergeOpenGraph(),
twitter: {
card: 'summary_large_image',

View File

@@ -9,6 +9,7 @@ import { Button } from '@/components/ui/button'
import { buildInitialFormState } from './buildInitialFormState'
import { fields } from './fields'
import { getClientSideURL } from '@/utilities/getURL'
export type Value = unknown
@@ -74,7 +75,7 @@ export const FormBlock: React.FC<
}, 1000)
try {
const req = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/form-submissions`, {
const req = await fetch(`${getClientSideURL()}/api/form-submissions`, {
body: JSON.stringify({
form: formID,
submissionData: dataToSend,

View File

@@ -20,6 +20,8 @@ import {
OverviewField,
PreviewField,
} from '@payloadcms/plugin-seo/fields'
import { getServerSideURL } from '@/utilities/getURL'
export const Pages: CollectionConfig = {
slug: 'pages',
access: {
@@ -37,7 +39,7 @@ export const Pages: CollectionConfig = {
collection: 'pages',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
},
preview: (data) => {
@@ -46,7 +48,7 @@ export const Pages: CollectionConfig = {
collection: 'pages',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
useAsTitle: 'title',
},

View File

@@ -26,6 +26,7 @@ import {
PreviewField,
} from '@payloadcms/plugin-seo/fields'
import { slugField } from '@/fields/slug'
import { getServerSideURL } from '@/utilities/getURL'
export const Posts: CollectionConfig = {
slug: 'posts',
@@ -44,7 +45,7 @@ export const Posts: CollectionConfig = {
collection: 'posts',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
},
preview: (data) => {
@@ -53,7 +54,7 @@ export const Posts: CollectionConfig = {
collection: 'posts',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
useAsTitle: 'title',
},

View File

@@ -10,6 +10,8 @@ import { useRouter } from 'next/navigation'
import './index.scss'
import { getClientSideURL } from '@/utilities/getURL'
const baseClass = 'admin-bar'
const collectionLabels = {
@@ -58,7 +60,7 @@ export const AdminBar: React.FC<{
logo: 'text-white',
user: 'text-white',
}}
cmsURL={process.env.NEXT_PUBLIC_SERVER_URL}
cmsURL={getClientSideURL()}
collection={collection}
collectionLabels={{
plural: collectionLabels[collection]?.plural || 'Pages',

View File

@@ -1,11 +1,10 @@
'use client'
import { getClientSideURL } from '@/utilities/getURL'
import { RefreshRouteOnSave as PayloadLivePreview } from '@payloadcms/live-preview-react'
import { useRouter } from 'next/navigation'
import React from 'react'
export const LivePreviewListener: React.FC = () => {
const router = useRouter()
return (
<PayloadLivePreview refresh={router.refresh} serverURL={process.env.NEXT_PUBLIC_SERVER_URL!} />
)
return <PayloadLivePreview refresh={router.refresh} serverURL={getClientSideURL()} />
}

View File

@@ -9,6 +9,7 @@ import React from 'react'
import type { Props as MediaProps } from '../types'
import cssVariables from '@/cssVariables'
import { getClientSideURL } from '@/utilities/getURL'
const { breakpoints } = cssVariables
@@ -45,7 +46,7 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {
height = fullHeight!
alt = altFromResource || ''
src = `${process.env.NEXT_PUBLIC_SERVER_URL}${url}`
src = `${getClientSideURL()}${url}`
}
// NOTE: this is used by the browser to determine which image to download at different screen sizes

View File

@@ -5,6 +5,8 @@ import React, { useEffect, useRef } from 'react'
import type { Props as MediaProps } from '../types'
import { getClientSideURL } from '@/utilities/getURL'
export const VideoMedia: React.FC<MediaProps> = (props) => {
const { onClick, resource, videoClassName } = props
@@ -35,7 +37,7 @@ export const VideoMedia: React.FC<MediaProps> = (props) => {
playsInline
ref={videoRef}
>
<source src={`${process.env.NEXT_PUBLIC_SERVER_URL}/media/${filename}`} />
<source src={`${getClientSideURL()}/media/${filename}`} />
</video>
)
}

View File

@@ -4,6 +4,7 @@ declare global {
PAYLOAD_SECRET: string
DATABASE_URI: string
NEXT_PUBLIC_SERVER_URL: string
VERCEL_PROJECT_PRODUCTION_URL: string
}
}
}

View File

@@ -15,6 +15,7 @@ import { Footer } from './Footer/config'
import { Header } from './Header/config'
import { plugins } from './plugins'
import { defaultLexical } from '@/fields/defaultLexical'
import { getServerSideURL } from './utilities/getURL'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@@ -64,7 +65,7 @@ export default buildConfig({
}),
// database-adapter-config-end
collections: [Pages, Posts, Media, Categories, Users],
cors: [process.env.NEXT_PUBLIC_SERVER_URL || ''].filter(Boolean),
cors: [getServerSideURL()].filter(Boolean),
globals: [Header, Footer],
plugins: [
...plugins,

View File

@@ -12,15 +12,16 @@ import { searchFields } from '@/search/fieldOverrides'
import { beforeSyncWithSearch } from '@/search/beforeSync'
import { Page, Post } from '@/payload-types'
import { getServerSideURL } from '@/utilities/getURL'
const generateTitle: GenerateTitle<Post | Page> = ({ doc }) => {
return doc?.title ? `${doc.title} | Payload Website Template` : 'Payload Website Template'
}
const generateURL: GenerateURL<Post | Page> = ({ doc }) => {
return doc?.slug
? `${process.env.NEXT_PUBLIC_SERVER_URL!}/${doc.slug}`
: process.env.NEXT_PUBLIC_SERVER_URL!
const url = getServerSideURL()
return doc?.slug ? `${url}/${doc.slug}` : url
}
export const plugins: Plugin[] = [

View File

@@ -3,6 +3,7 @@ import type { Metadata } from 'next'
import type { Page, Post } from '../payload-types'
import { mergeOpenGraph } from './mergeOpenGraph'
import { getServerSideURL } from './getURL'
export const generateMeta = async (args: { doc: Page | Post }): Promise<Metadata> => {
const { doc } = args || {}
@@ -11,7 +12,7 @@ export const generateMeta = async (args: { doc: Page | Post }): Promise<Metadata
typeof doc?.meta?.image === 'object' &&
doc.meta.image !== null &&
'url' in doc.meta.image &&
`${process.env.NEXT_PUBLIC_SERVER_URL}${doc.meta.image.url}`
`${getServerSideURL()}`
const title = doc?.meta?.title
? doc?.meta?.title + ' | Payload Website Template'

View File

@@ -2,6 +2,7 @@ import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
import type { User } from '../payload-types'
import { getClientSideURL } from './getURL'
export const getMeUser = async (args?: {
nullUserRedirect?: string
@@ -14,7 +15,7 @@ export const getMeUser = async (args?: {
const cookieStore = await cookies()
const token = cookieStore.get('payload-token')?.value
const meUserReq = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/users/me`, {
const meUserReq = await fetch(`${getClientSideURL()}/api/users/me`, {
headers: {
Authorization: `JWT ${token}`,
},

View File

@@ -0,0 +1,27 @@
import canUseDOM from './canUseDOM'
export const getServerSideURL = () => {
let url = process.env.NEXT_PUBLIC_SERVER_URL
if (!url && process.env.VERCEL_PROJECT_PRODUCTION_URL) {
return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
}
if (!url) {
url = 'http://localhost:3000'
}
return url
}
export const getClientSideURL = () => {
if (canUseDOM) {
const protocol = window.location.protocol
const domain = window.location.hostname
const port = window.location.port
return `${protocol}//${domain}${port ? `:${port}` : ''}`
}
return ''
}

View File

@@ -1,13 +1,12 @@
import type { Metadata } from 'next'
import { getServerSideURL } from './getURL'
const defaultOpenGraph: Metadata['openGraph'] = {
type: 'website',
description: 'An open-source website built with Payload and Next.js.',
images: [
{
url: process.env.NEXT_PUBLIC_SERVER_URL
? `${process.env.NEXT_PUBLIC_SERVER_URL}/website-template-OG.webp`
: '/website-template-OG.webp',
url: `${getServerSideURL()}/website-template-OG.webp`,
},
],
siteName: 'Payload Website Template',

View File

@@ -15,6 +15,7 @@ import { mergeOpenGraph } from '@/utilities/mergeOpenGraph'
import { draftMode } from 'next/headers'
import './globals.css'
import { getServerSideURL } from '@/utilities/getURL'
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const { isEnabled } = await draftMode()
@@ -45,7 +46,7 @@ export default async function RootLayout({ children }: { children: React.ReactNo
}
export const metadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_SERVER_URL || 'https://payloadcms.com'),
metadataBase: new URL(getServerSideURL()),
openGraph: mergeOpenGraph(),
twitter: {
card: 'summary_large_image',

View File

@@ -9,6 +9,7 @@ import { Button } from '@/components/ui/button'
import { buildInitialFormState } from './buildInitialFormState'
import { fields } from './fields'
import { getClientSideURL } from '@/utilities/getURL'
export type Value = unknown
@@ -74,7 +75,7 @@ export const FormBlock: React.FC<
}, 1000)
try {
const req = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/form-submissions`, {
const req = await fetch(`${getClientSideURL()}/api/form-submissions`, {
body: JSON.stringify({
form: formID,
submissionData: dataToSend,

View File

@@ -20,6 +20,8 @@ import {
OverviewField,
PreviewField,
} from '@payloadcms/plugin-seo/fields'
import { getServerSideURL } from '@/utilities/getURL'
export const Pages: CollectionConfig = {
slug: 'pages',
access: {
@@ -37,7 +39,7 @@ export const Pages: CollectionConfig = {
collection: 'pages',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
},
preview: (data) => {
@@ -46,7 +48,7 @@ export const Pages: CollectionConfig = {
collection: 'pages',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
useAsTitle: 'title',
},

View File

@@ -26,6 +26,7 @@ import {
PreviewField,
} from '@payloadcms/plugin-seo/fields'
import { slugField } from '@/fields/slug'
import { getServerSideURL } from '@/utilities/getURL'
export const Posts: CollectionConfig = {
slug: 'posts',
@@ -44,7 +45,7 @@ export const Posts: CollectionConfig = {
collection: 'posts',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
},
preview: (data) => {
@@ -53,7 +54,7 @@ export const Posts: CollectionConfig = {
collection: 'posts',
})
return `${process.env.NEXT_PUBLIC_SERVER_URL}${path}`
return `${getServerSideURL()}${path}`
},
useAsTitle: 'title',
},

View File

@@ -9,6 +9,7 @@ import React, { useState } from 'react'
import { useRouter } from 'next/navigation'
import './index.scss'
import { getClientSideURL } from '@/utilities/getURL'
const baseClass = 'admin-bar'
@@ -58,7 +59,7 @@ export const AdminBar: React.FC<{
logo: 'text-white',
user: 'text-white',
}}
cmsURL={process.env.NEXT_PUBLIC_SERVER_URL}
cmsURL={getClientSideURL()}
collection={collection}
collectionLabels={{
plural: collectionLabels[collection]?.plural || 'Pages',

View File

@@ -1,11 +1,10 @@
'use client'
import { getClientSideURL } from '@/utilities/getURL'
import { RefreshRouteOnSave as PayloadLivePreview } from '@payloadcms/live-preview-react'
import { useRouter } from 'next/navigation'
import React from 'react'
export const LivePreviewListener: React.FC = () => {
const router = useRouter()
return (
<PayloadLivePreview refresh={router.refresh} serverURL={process.env.NEXT_PUBLIC_SERVER_URL!} />
)
return <PayloadLivePreview refresh={router.refresh} serverURL={getClientSideURL()} />
}

View File

@@ -9,6 +9,7 @@ import React from 'react'
import type { Props as MediaProps } from '../types'
import cssVariables from '@/cssVariables'
import { getClientSideURL } from '@/utilities/getURL'
const { breakpoints } = cssVariables
@@ -45,7 +46,7 @@ export const ImageMedia: React.FC<MediaProps> = (props) => {
height = fullHeight!
alt = altFromResource || ''
src = `${process.env.NEXT_PUBLIC_SERVER_URL}${url}`
src = `${getClientSideURL()}${url}`
}
// NOTE: this is used by the browser to determine which image to download at different screen sizes

View File

@@ -4,6 +4,7 @@ import { cn } from 'src/utilities/cn'
import React, { useEffect, useRef } from 'react'
import type { Props as MediaProps } from '../types'
import { getClientSideURL } from '@/utilities/getURL'
export const VideoMedia: React.FC<MediaProps> = (props) => {
const { onClick, resource, videoClassName } = props
@@ -35,7 +36,7 @@ export const VideoMedia: React.FC<MediaProps> = (props) => {
playsInline
ref={videoRef}
>
<source src={`${process.env.NEXT_PUBLIC_SERVER_URL}/media/${filename}`} />
<source src={`${getClientSideURL()}/media/${filename}`} />
</video>
)
}

View File

@@ -4,6 +4,7 @@ declare global {
PAYLOAD_SECRET: string
DATABASE_URI: string
NEXT_PUBLIC_SERVER_URL: string
VERCEL_PROJECT_PRODUCTION_URL: string
}
}
}

View File

@@ -15,6 +15,7 @@ import { Footer } from './Footer/config'
import { Header } from './Header/config'
import { plugins } from './plugins'
import { defaultLexical } from '@/fields/defaultLexical'
import { getServerSideURL } from './utilities/getURL'
const filename = fileURLToPath(import.meta.url)
const dirname = path.dirname(filename)
@@ -64,7 +65,7 @@ export default buildConfig({
},
}),
collections: [Pages, Posts, Media, Categories, Users],
cors: [process.env.NEXT_PUBLIC_SERVER_URL || ''].filter(Boolean),
cors: [getServerSideURL()].filter(Boolean),
globals: [Header, Footer],
plugins: [
...plugins,

View File

@@ -12,15 +12,16 @@ import { searchFields } from '@/search/fieldOverrides'
import { beforeSyncWithSearch } from '@/search/beforeSync'
import { Page, Post } from '@/payload-types'
import { getServerSideURL } from '@/utilities/getURL'
const generateTitle: GenerateTitle<Post | Page> = ({ doc }) => {
return doc?.title ? `${doc.title} | Payload Website Template` : 'Payload Website Template'
}
const generateURL: GenerateURL<Post | Page> = ({ doc }) => {
return doc?.slug
? `${process.env.NEXT_PUBLIC_SERVER_URL!}/${doc.slug}`
: process.env.NEXT_PUBLIC_SERVER_URL!
const url = getServerSideURL()
return doc?.slug ? `${url}/${doc.slug}` : url
}
export const plugins: Plugin[] = [

View File

@@ -3,6 +3,7 @@ import type { Metadata } from 'next'
import type { Page, Post } from '../payload-types'
import { mergeOpenGraph } from './mergeOpenGraph'
import { getServerSideURL } from './getURL'
export const generateMeta = async (args: { doc: Page | Post }): Promise<Metadata> => {
const { doc } = args || {}
@@ -11,7 +12,7 @@ export const generateMeta = async (args: { doc: Page | Post }): Promise<Metadata
typeof doc?.meta?.image === 'object' &&
doc.meta.image !== null &&
'url' in doc.meta.image &&
`${process.env.NEXT_PUBLIC_SERVER_URL}${doc.meta.image.url}`
`${getServerSideURL()}`
const title = doc?.meta?.title
? doc?.meta?.title + ' | Payload Website Template'

View File

@@ -2,6 +2,7 @@ import { cookies } from 'next/headers'
import { redirect } from 'next/navigation'
import type { User } from '../payload-types'
import { getClientSideURL } from './getURL'
export const getMeUser = async (args?: {
nullUserRedirect?: string
@@ -14,7 +15,7 @@ export const getMeUser = async (args?: {
const cookieStore = await cookies()
const token = cookieStore.get('payload-token')?.value
const meUserReq = await fetch(`${process.env.NEXT_PUBLIC_SERVER_URL}/api/users/me`, {
const meUserReq = await fetch(`${getClientSideURL()}/api/users/me`, {
headers: {
Authorization: `JWT ${token}`,
},

View File

@@ -0,0 +1,27 @@
import canUseDOM from './canUseDOM'
export const getServerSideURL = () => {
let url = process.env.NEXT_PUBLIC_SERVER_URL
if (!url && process.env.VERCEL_PROJECT_PRODUCTION_URL) {
return `https://${process.env.VERCEL_PROJECT_PRODUCTION_URL}`
}
if (!url) {
url = 'http://localhost:3000'
}
return url
}
export const getClientSideURL = () => {
if (canUseDOM) {
const protocol = window.location.protocol
const domain = window.location.hostname
const port = window.location.port
return `${protocol}//${domain}${port ? `:${port}` : ''}`
}
return ''
}

View File

@@ -1,13 +1,12 @@
import type { Metadata } from 'next'
import { getServerSideURL } from './getURL'
const defaultOpenGraph: Metadata['openGraph'] = {
type: 'website',
description: 'An open-source website built with Payload and Next.js.',
images: [
{
url: process.env.NEXT_PUBLIC_SERVER_URL
? `${process.env.NEXT_PUBLIC_SERVER_URL}/website-template-OG.webp`
: '/website-template-OG.webp',
url: `${getServerSideURL()}/website-template-OG.webp`,
},
],
siteName: 'Payload Website Template',