chore(examples): Cosmic cms updates (#41080)
Lands #38163 with merge conflict fixes. Needed to open a new PR, because GitHub does not allow maintainers to edit organization forks. https://github.com/orgs/community/discussions/5634 Closes #38163 ## Bug - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Errors have a helpful link attached, see `contributing.md` ## Feature - [ ] Implements an existing feature request or RFC. Make sure the feature request has been accepted for implementation before opening a PR. - [ ] Related issues linked using `fixes #number` - [ ] Integration tests added - [ ] Documentation added - [ ] Telemetry added. In case of a feature if it's used or not. - [ ] Errors have a helpful link attached, see `contributing.md` ## Documentation / Examples - [ ] Make sure the linting passes by running `pnpm lint` - [ ] The "examples guidelines" are followed from [our contributing doc](https://github.com/vercel/next.js/blob/canary/contributing/examples/adding-examples.md) Co-authored-by: sherazmalik06 <sherazmalik06@gmail.com> Co-authored-by: Tony Spiro <tspiro@tonyspiro.com>
This commit is contained in:
parent
e875dded8b
commit
3caebdef67
33 changed files with 293 additions and 83 deletions
|
@ -2,7 +2,12 @@ import Container from './container'
|
|||
import cn from 'classnames'
|
||||
import { EXAMPLE_PATH } from '@/lib/constants'
|
||||
|
||||
export default function Alert({ preview }) {
|
||||
type AlertProps = {
|
||||
preview: boolean
|
||||
}
|
||||
|
||||
const Alert = (props: AlertProps) => {
|
||||
const { preview } = props
|
||||
return (
|
||||
<div
|
||||
className={cn('border-b', {
|
||||
|
@ -14,7 +19,7 @@ export default function Alert({ preview }) {
|
|||
<div className="py-2 text-center text-sm">
|
||||
{preview ? (
|
||||
<>
|
||||
This is page is a preview.{' '}
|
||||
This page is a preview.{' '}
|
||||
<a
|
||||
href="/api/exit-preview"
|
||||
className="underline hover:text-cyan duration-200 transition-colors"
|
||||
|
@ -40,3 +45,5 @@ export default function Alert({ preview }) {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Alert
|
|
@ -1,6 +1,13 @@
|
|||
import Image from 'next/image'
|
||||
|
||||
export default function Avatar({ name, picture }) {
|
||||
type AvatarProps = {
|
||||
name: string
|
||||
picture: string
|
||||
}
|
||||
|
||||
const Avatar = (props: AvatarProps) => {
|
||||
const { name, picture } = props
|
||||
|
||||
return (
|
||||
<div className="flex items-center">
|
||||
<div className="w-12 h-12 relative mr-4">
|
||||
|
@ -17,3 +24,5 @@ export default function Avatar({ name, picture }) {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default Avatar
|
|
@ -1,3 +0,0 @@
|
|||
export default function Container({ children }) {
|
||||
return <div className="container mx-auto px-5">{children}</div>
|
||||
}
|
12
examples/cms-cosmic/components/container.tsx
Normal file
12
examples/cms-cosmic/components/container.tsx
Normal file
|
@ -0,0 +1,12 @@
|
|||
import { ReactNode } from 'react'
|
||||
|
||||
type ContainerProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const Container = (props: ContainerProps) => {
|
||||
const { children } = props
|
||||
return <div className="container mx-auto px-5">{children}</div>
|
||||
}
|
||||
|
||||
export default Container
|
|
@ -2,7 +2,14 @@ import cn from 'classnames'
|
|||
import Link from 'next/link'
|
||||
import Imgix from 'react-imgix'
|
||||
|
||||
export default function CoverImage({ title, url, slug }) {
|
||||
type CoverImageProps = {
|
||||
title
|
||||
url
|
||||
slug
|
||||
}
|
||||
const CoverImage = (props: CoverImageProps) => {
|
||||
const { title, url, slug } = props
|
||||
|
||||
const image = (
|
||||
<Imgix
|
||||
src={url}
|
||||
|
@ -33,3 +40,4 @@ export default function CoverImage({ title, url, slug }) {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
export default CoverImage
|
|
@ -1,6 +1,13 @@
|
|||
import { parseISO, format } from 'date-fns'
|
||||
|
||||
export default function Date({ dateString }) {
|
||||
type DateProps = {
|
||||
dateString: string
|
||||
}
|
||||
|
||||
const Date = (props: DateProps) => {
|
||||
const { dateString } = props
|
||||
const date = parseISO(dateString)
|
||||
return <time dateTime={dateString}>{format(date, 'LLLL d, yyyy')}</time>
|
||||
}
|
||||
|
||||
export default Date
|
|
@ -1,7 +1,7 @@
|
|||
import Container from './container'
|
||||
import { EXAMPLE_PATH } from '@/lib/constants'
|
||||
|
||||
export default function Footer() {
|
||||
const Footer = () => {
|
||||
return (
|
||||
<footer className="bg-accent-1 border-t border-accent-2">
|
||||
<Container>
|
||||
|
@ -28,3 +28,5 @@ export default function Footer() {
|
|||
</footer>
|
||||
)
|
||||
}
|
||||
|
||||
export default Footer
|
|
@ -1,6 +1,6 @@
|
|||
import Link from 'next/link'
|
||||
|
||||
export default function Header() {
|
||||
const Header = () => {
|
||||
return (
|
||||
<h2 className="text-2xl md:text-4xl font-bold tracking-tight md:tracking-tighter leading-tight mb-20 mt-8">
|
||||
<Link href="/">
|
||||
|
@ -10,3 +10,5 @@ export default function Header() {
|
|||
</h2>
|
||||
)
|
||||
}
|
||||
|
||||
export default Header
|
|
@ -2,15 +2,20 @@ import Avatar from './avatar'
|
|||
import Date from './date'
|
||||
import CoverImage from './cover-image'
|
||||
import Link from 'next/link'
|
||||
import { AuthorType, ImgixType } from 'interfaces'
|
||||
|
||||
type HeroPostProps = {
|
||||
title: string
|
||||
coverImage: ImgixType
|
||||
date: string
|
||||
excerpt: string
|
||||
author: AuthorType
|
||||
slug: string
|
||||
}
|
||||
|
||||
const HeroPost = (props: HeroPostProps) => {
|
||||
const { title, coverImage, date, excerpt, author, slug } = props
|
||||
|
||||
export default function HeroPost({
|
||||
title,
|
||||
coverImage,
|
||||
date,
|
||||
excerpt,
|
||||
author,
|
||||
slug,
|
||||
}) {
|
||||
return (
|
||||
<section>
|
||||
<div className="mb-8 md:mb-16">
|
||||
|
@ -38,3 +43,5 @@ export default function HeroPost({
|
|||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default HeroPost
|
|
@ -1,6 +1,6 @@
|
|||
import { CMS_NAME, CMS_URL } from '@/lib/constants'
|
||||
|
||||
export default function Intro() {
|
||||
const Intro = () => {
|
||||
return (
|
||||
<section className="flex-col md:flex-row flex items-center md:justify-between mt-16 mb-16 md:mb-12">
|
||||
<h1 className="text-6xl md:text-8xl font-bold tracking-tighter leading-tight md:pr-8">
|
||||
|
@ -26,3 +26,5 @@ export default function Intro() {
|
|||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default Intro
|
|
@ -3,8 +3,14 @@ import Footer from './footer'
|
|||
import Meta from './meta'
|
||||
import 'lazysizes'
|
||||
import 'lazysizes/plugins/parent-fit/ls.parent-fit'
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
export default function Layout({ preview, children }) {
|
||||
type LayoutProps = {
|
||||
preview: boolean
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const Layout = ({ preview, children }: LayoutProps) => {
|
||||
return (
|
||||
<>
|
||||
<Meta />
|
||||
|
@ -16,3 +22,5 @@ export default function Layout({ preview, children }) {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default Layout
|
|
@ -1,7 +1,7 @@
|
|||
import Head from 'next/head'
|
||||
import { CMS_NAME, HOME_OG_IMAGE_URL } from '@/lib/constants'
|
||||
|
||||
export default function Meta() {
|
||||
const Meta = () => {
|
||||
return (
|
||||
<Head>
|
||||
<link
|
||||
|
@ -40,3 +40,5 @@ export default function Meta() {
|
|||
</Head>
|
||||
)
|
||||
}
|
||||
|
||||
export default Meta
|
|
@ -1,6 +1,12 @@
|
|||
import { PostType } from 'interfaces'
|
||||
import PostPreview from './post-preview'
|
||||
|
||||
export default function MoreStories({ posts }) {
|
||||
type MoreStoriesProps = {
|
||||
posts: PostType[]
|
||||
}
|
||||
|
||||
const MoreStories = (props: MoreStoriesProps) => {
|
||||
const { posts } = props
|
||||
return (
|
||||
<section>
|
||||
<h2 className="mb-8 text-6xl md:text-7xl font-bold tracking-tighter leading-tight">
|
||||
|
@ -22,3 +28,5 @@ export default function MoreStories({ posts }) {
|
|||
</section>
|
||||
)
|
||||
}
|
||||
|
||||
export default MoreStories
|
|
@ -1,6 +1,11 @@
|
|||
import markdownStyles from './markdown-styles.module.css'
|
||||
|
||||
export default function PostBody({ content }) {
|
||||
type PostBodyProps = {
|
||||
content: string
|
||||
}
|
||||
|
||||
const PostBody = (props: PostBodyProps) => {
|
||||
const { content } = props
|
||||
return (
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div
|
||||
|
@ -10,3 +15,5 @@ export default function PostBody({ content }) {
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PostBody
|
|
@ -2,8 +2,17 @@ import Avatar from './avatar'
|
|||
import Date from './date'
|
||||
import CoverImage from './cover-image'
|
||||
import PostTitle from './post-title'
|
||||
import { AuthorType, ImgixType } from 'interfaces'
|
||||
|
||||
export default function PostHeader({ title, coverImage, date, author }) {
|
||||
type PostHeaderProps = {
|
||||
title: string
|
||||
coverImage: ImgixType
|
||||
date: string
|
||||
author: AuthorType
|
||||
}
|
||||
|
||||
const PostHeader = (props: PostHeaderProps) => {
|
||||
const { title, coverImage, date, author } = props
|
||||
return (
|
||||
<>
|
||||
<PostTitle>{title}</PostTitle>
|
||||
|
@ -14,11 +23,14 @@ export default function PostHeader({ title, coverImage, date, author }) {
|
|||
/>
|
||||
</div>
|
||||
<div className="mb-8 md:mb-16 sm:mx-0">
|
||||
<CoverImage title={title} url={coverImage.imgix_url} />
|
||||
<CoverImage title={title} url={coverImage.imgix_url} slug={''} />
|
||||
</div>
|
||||
<div className="max-w-2xl mx-auto">
|
||||
<div className="block md:hidden mb-6">
|
||||
<Avatar name={author.name} picture={author.picture} />
|
||||
<Avatar
|
||||
name={author.title}
|
||||
picture={author.metadata.picture.imgix_url}
|
||||
/>
|
||||
</div>
|
||||
<div className="mb-6 text-lg">
|
||||
<Date dateString={date} />
|
||||
|
@ -27,3 +39,5 @@ export default function PostHeader({ title, coverImage, date, author }) {
|
|||
</>
|
||||
)
|
||||
}
|
||||
|
||||
export default PostHeader
|
|
@ -2,15 +2,20 @@ import Avatar from './avatar'
|
|||
import Date from './date'
|
||||
import CoverImage from './cover-image'
|
||||
import Link from 'next/link'
|
||||
import { AuthorType, ImgixType } from 'interfaces'
|
||||
|
||||
type PostPreviewProps = {
|
||||
title: string
|
||||
coverImage: ImgixType
|
||||
date: string
|
||||
excerpt: string
|
||||
author: AuthorType
|
||||
slug: string
|
||||
}
|
||||
|
||||
const PostPreview = (props: PostPreviewProps) => {
|
||||
const { title, coverImage, date, excerpt, author, slug } = props
|
||||
|
||||
export default function PostPreview({
|
||||
title,
|
||||
coverImage,
|
||||
date,
|
||||
excerpt,
|
||||
author,
|
||||
slug,
|
||||
}) {
|
||||
return (
|
||||
<div>
|
||||
<div className="mb-5">
|
||||
|
@ -29,3 +34,5 @@ export default function PostPreview({
|
|||
</div>
|
||||
)
|
||||
}
|
||||
|
||||
export default PostPreview
|
|
@ -1,7 +1,15 @@
|
|||
export default function PostTitle({ children }) {
|
||||
import { ReactNode } from 'react'
|
||||
|
||||
type PostTitleProps = {
|
||||
children: ReactNode
|
||||
}
|
||||
|
||||
const PostTitle = (props: PostTitleProps) => {
|
||||
const { children } = props
|
||||
return (
|
||||
<h1 className="text-6xl md:text-7xl lg:text-8xl font-bold tracking-tighter leading-tight md:leading-none mb-12 text-center md:text-left">
|
||||
{children}
|
||||
</h1>
|
||||
)
|
||||
}
|
||||
export default PostTitle
|
|
@ -1,3 +0,0 @@
|
|||
export default function SectionSeparator() {
|
||||
return <hr className="border-accent-2 mt-28 mb-24" />
|
||||
}
|
5
examples/cms-cosmic/components/section-separator.tsx
Normal file
5
examples/cms-cosmic/components/section-separator.tsx
Normal file
|
@ -0,0 +1,5 @@
|
|||
const SectionSeparator = () => {
|
||||
return <hr className="border-accent-2 mt-28 mb-24" />
|
||||
}
|
||||
|
||||
export default SectionSeparator
|
24
examples/cms-cosmic/interfaces/index.ts
Normal file
24
examples/cms-cosmic/interfaces/index.ts
Normal file
|
@ -0,0 +1,24 @@
|
|||
export type ImgixType = {
|
||||
url: string
|
||||
imgix_url: string
|
||||
}
|
||||
|
||||
export type AuthorType = {
|
||||
title: string
|
||||
metadata: {
|
||||
picture: ImgixType
|
||||
}
|
||||
}
|
||||
|
||||
export type PostType = {
|
||||
title: string
|
||||
slug: string
|
||||
content: string
|
||||
created_at: string
|
||||
metadata: {
|
||||
cover_image: ImgixType
|
||||
author: AuthorType
|
||||
excerpt: string
|
||||
content: string
|
||||
}
|
||||
}
|
|
@ -1,4 +1,5 @@
|
|||
import Cosmic from 'cosmicjs'
|
||||
import { PostType } from 'interfaces'
|
||||
import ErrorPage from 'next/error'
|
||||
|
||||
const BUCKET_SLUG = process.env.COSMIC_BUCKET_SLUG
|
||||
|
@ -9,26 +10,26 @@ const bucket = Cosmic().bucket({
|
|||
read_key: READ_KEY,
|
||||
})
|
||||
|
||||
export async function getPreviewPostBySlug(slug) {
|
||||
export const getPreviewPostBySlug = async (slug: string) => {
|
||||
const params = {
|
||||
query: {
|
||||
slug,
|
||||
type: 'posts',
|
||||
},
|
||||
props: 'slug',
|
||||
status: 'all',
|
||||
status: 'any',
|
||||
}
|
||||
|
||||
try {
|
||||
const data = await bucket.getObjects(params)
|
||||
return data.objects[0]
|
||||
} catch (err) {
|
||||
// 404 if slug not found
|
||||
// Don't throw if an slug doesn't exist
|
||||
return <ErrorPage statusCode={err.status} />
|
||||
}
|
||||
}
|
||||
|
||||
export async function getAllPostsWithSlug() {
|
||||
export const getAllPostsWithSlug = async () => {
|
||||
const params = {
|
||||
query: {
|
||||
type: 'posts',
|
||||
|
@ -39,27 +40,33 @@ export async function getAllPostsWithSlug() {
|
|||
return data.objects
|
||||
}
|
||||
|
||||
export async function getAllPostsForHome(preview) {
|
||||
export const getAllPostsForHome = async (preview: boolean): Promise<Post[]> => {
|
||||
const params = {
|
||||
query: {
|
||||
type: 'posts',
|
||||
},
|
||||
props: 'title,slug,metadata,created_at',
|
||||
sort: '-created_at',
|
||||
...(preview && { status: 'all' }),
|
||||
...(preview && { status: 'any' }),
|
||||
}
|
||||
const data = await bucket.getObjects(params)
|
||||
return data.objects
|
||||
}
|
||||
|
||||
export async function getPostAndMorePosts(slug, preview) {
|
||||
export const getPostAndMorePosts = async (
|
||||
slug: string,
|
||||
preview: boolean
|
||||
): Promise<{
|
||||
post: PostType
|
||||
morePosts: PostType[]
|
||||
}> => {
|
||||
const singleObjectParams = {
|
||||
query: {
|
||||
slug,
|
||||
type: 'posts',
|
||||
},
|
||||
props: 'slug,title,metadata,created_at',
|
||||
...(preview && { status: 'all' }),
|
||||
...(preview && { status: 'any' }),
|
||||
}
|
||||
const moreObjectParams = {
|
||||
query: {
|
||||
|
@ -67,15 +74,14 @@ export async function getPostAndMorePosts(slug, preview) {
|
|||
},
|
||||
limit: 3,
|
||||
props: 'title,slug,metadata,created_at',
|
||||
...(preview && { status: 'all' }),
|
||||
...(preview && { status: 'any' }),
|
||||
}
|
||||
let object
|
||||
try {
|
||||
const data = await bucket.getObjects(singleObjectParams)
|
||||
object = data.objects[0]
|
||||
} catch (err) {
|
||||
// 404 if slug not found
|
||||
return <ErrorPage statusCode={err.status} />
|
||||
throw err
|
||||
}
|
||||
const moreObjects = await bucket.getObjects(moreObjectParams)
|
||||
const morePosts = moreObjects.objects
|
|
@ -1,7 +1,9 @@
|
|||
import { remark } from 'remark'
|
||||
import html from 'remark-html'
|
||||
|
||||
export default async function markdownToHtml(markdown) {
|
||||
const markdownToHtml = async (markdown: string) => {
|
||||
const result = await remark().use(html).process(markdown)
|
||||
return result.toString()
|
||||
}
|
||||
|
||||
export default markdownToHtml
|
5
examples/cms-cosmic/next-env.d.ts
vendored
Normal file
5
examples/cms-cosmic/next-env.d.ts
vendored
Normal file
|
@ -0,0 +1,5 @@
|
|||
/// <reference types="next" />
|
||||
/// <reference types="next/image-types/global" />
|
||||
|
||||
// NOTE: This file should not be edited
|
||||
// see https://nextjs.org/docs/basic-features/typescript for more information.
|
|
@ -9,18 +9,20 @@
|
|||
"classnames": "2.3.1",
|
||||
"cosmicjs": "4.1.7",
|
||||
"date-fns": "2.28.0",
|
||||
"lazysizes": "^5.2.1-rc2",
|
||||
"lazysizes": "^5.3.2",
|
||||
"next": "latest",
|
||||
"react": "^17.0.2",
|
||||
"react-datocms": "1.6.3",
|
||||
"react-dom": "^17.0.2",
|
||||
"react-imgix": "^9.0.2",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0",
|
||||
"react-imgix": "^9.5.1",
|
||||
"remark": "14.0.2",
|
||||
"remark-html": "15.0.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"autoprefixer": "10.4.2",
|
||||
"postcss": "8.4.5",
|
||||
"tailwindcss": "^3.0.15"
|
||||
"@types/node": "^18.0.0",
|
||||
"@types/react": "^18.0.14",
|
||||
"autoprefixer": "10.4.7",
|
||||
"postcss": "8.4.14",
|
||||
"tailwindcss": "^3.1.4",
|
||||
"typescript": "^4.7.4"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,7 +0,0 @@
|
|||
import '@/styles/index.css'
|
||||
|
||||
function MyApp({ Component, pageProps }) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
|
||||
export default MyApp
|
8
examples/cms-cosmic/pages/_app.tsx
Normal file
8
examples/cms-cosmic/pages/_app.tsx
Normal file
|
@ -0,0 +1,8 @@
|
|||
import '@/styles/index.css'
|
||||
import type { AppProps } from 'next/app'
|
||||
|
||||
function MyApp({ Component, pageProps }: AppProps) {
|
||||
return <Component {...pageProps} />
|
||||
}
|
||||
|
||||
export default MyApp
|
|
@ -1,4 +1,4 @@
|
|||
export default async function exit(_, res) {
|
||||
export default function exit (_, res) {
|
||||
// Exit the current user from "Preview Mode". This function accepts no args.
|
||||
res.clearPreviewData()
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
import { getPreviewPostBySlug } from '@/lib/api'
|
||||
|
||||
export default async function preview(req, res) {
|
||||
// Check the secret and next parameters
|
||||
// Check the secret and next parameters
|
||||
// This secret should only be known to this API route and the CMS
|
||||
if (
|
||||
req.query.secret !== process.env.COSMIC_PREVIEW_SECRET ||
|
|
@ -6,13 +6,22 @@ import Layout from '@/components/layout'
|
|||
import { getAllPostsForHome } from '@/lib/api'
|
||||
import Head from 'next/head'
|
||||
import { CMS_NAME } from '@/lib/constants'
|
||||
import { PostType } from 'interfaces'
|
||||
|
||||
type IndexProps = {
|
||||
allPosts: PostType[]
|
||||
preview: boolean
|
||||
}
|
||||
|
||||
const Index = (props: IndexProps) => {
|
||||
const { allPosts, preview } = props
|
||||
|
||||
export default function Index({ allPosts }) {
|
||||
const heroPost = allPosts[0]
|
||||
const morePosts = allPosts.slice(1)
|
||||
|
||||
return (
|
||||
<>
|
||||
<Layout>
|
||||
<Layout preview={preview}>
|
||||
<Head>
|
||||
<title>Next.js Blog Example with {CMS_NAME}</title>
|
||||
</Head>
|
||||
|
@ -35,9 +44,16 @@ export default function Index({ allPosts }) {
|
|||
)
|
||||
}
|
||||
|
||||
export async function getStaticProps({ preview }) {
|
||||
export default Index
|
||||
|
||||
type staticProps = {
|
||||
preview: boolean
|
||||
}
|
||||
|
||||
export const getStaticProps = async (props: staticProps) => {
|
||||
const { preview = null } = props
|
||||
const allPosts = (await getAllPostsForHome(preview)) || []
|
||||
return {
|
||||
props: { allPosts },
|
||||
props: { allPosts, preview },
|
||||
}
|
||||
}
|
|
@ -12,8 +12,17 @@ import PostTitle from '@/components/post-title'
|
|||
import Head from 'next/head'
|
||||
import { CMS_NAME } from '@/lib/constants'
|
||||
import markdownToHtml from '@/lib/markdownToHtml'
|
||||
import { PostType } from 'interfaces'
|
||||
import { ParsedUrlQueryInput } from 'querystring'
|
||||
|
||||
export default function Post({ post, morePosts, preview }) {
|
||||
type PostProps = {
|
||||
post: PostType
|
||||
morePosts: PostType[]
|
||||
preview
|
||||
}
|
||||
|
||||
const Post = (props: PostProps) => {
|
||||
const { post, morePosts, preview } = props
|
||||
const router = useRouter()
|
||||
if (!router.isFallback && !post?.slug) {
|
||||
return <ErrorPage statusCode={404} />
|
||||
|
@ -52,20 +61,30 @@ export default function Post({ post, morePosts, preview }) {
|
|||
</Layout>
|
||||
)
|
||||
}
|
||||
export default Post
|
||||
|
||||
export async function getStaticProps({ params, preview = null }) {
|
||||
const data = await getPostAndMorePosts(params.slug, preview)
|
||||
const content = await markdownToHtml(data.post?.metadata?.content || '')
|
||||
type staticProps = {
|
||||
params: ParsedUrlQueryInput
|
||||
preview: boolean
|
||||
}
|
||||
|
||||
return {
|
||||
props: {
|
||||
preview,
|
||||
post: {
|
||||
...data.post,
|
||||
content,
|
||||
export const getStaticProps = async (props: staticProps) => {
|
||||
const { params, preview = null } = props
|
||||
try {
|
||||
const data = await getPostAndMorePosts(params.slug as string, preview)
|
||||
const content = await markdownToHtml(data['post']?.metadata?.content || '')
|
||||
return {
|
||||
props: {
|
||||
preview,
|
||||
post: {
|
||||
...data['post'],
|
||||
content,
|
||||
},
|
||||
morePosts: data['morePosts'] || [],
|
||||
},
|
||||
morePosts: data.morePosts || [],
|
||||
},
|
||||
}
|
||||
} catch (err) {
|
||||
return <ErrorPage statusCode={err.status} />
|
||||
}
|
||||
}
|
||||
|
26
examples/cms-cosmic/tsconfig.json
Normal file
26
examples/cms-cosmic/tsconfig.json
Normal file
|
@ -0,0 +1,26 @@
|
|||
{
|
||||
"compilerOptions": {
|
||||
"baseUrl": ".",
|
||||
"paths": {
|
||||
"@/components/*": ["components/*"],
|
||||
"@/lib/*": ["lib/*"],
|
||||
"@/styles/*": ["styles/*"]
|
||||
},
|
||||
"target": "es5",
|
||||
"lib": ["dom", "dom.iterable", "esnext"],
|
||||
"allowJs": true,
|
||||
"skipLibCheck": true,
|
||||
"strict": false,
|
||||
"forceConsistentCasingInFileNames": true,
|
||||
"noEmit": true,
|
||||
"incremental": true,
|
||||
"esModuleInterop": true,
|
||||
"module": "esnext",
|
||||
"moduleResolution": "Node",
|
||||
"jsx": "preserve",
|
||||
"resolveJsonModule": true,
|
||||
"isolatedModules": true
|
||||
},
|
||||
"include": ["./components/..", "./lib/..", "./styles/.."],
|
||||
"exclude": ["node_modules"]
|
||||
}
|
Loading…
Reference in a new issue