├── .env.example ├── .gitignore ├── README.md ├── app ├── author │ └── [slug] │ │ └── page.tsx ├── layout.tsx ├── page.tsx └── posts │ └── [slug] │ └── page.tsx ├── components ├── ArrowLeft.tsx ├── ArrowRight.tsx ├── AuthorAttribution.tsx ├── AuthorAvatar.tsx ├── Banner.tsx ├── CosmicLogo.tsx ├── Footer.tsx ├── Header.tsx ├── OBMLogo.tsx ├── PostCard.tsx ├── SiteLogo.tsx ├── SuggestedPostCard.tsx └── Tag.tsx ├── fonts └── Generator-Variable.ttf ├── helpers.ts ├── lib ├── cosmic.ts └── types.ts ├── next.config.js ├── package.json ├── postcss.config.js ├── public └── favicon.ico ├── styles └── globals.css ├── tailwind.config.js ├── tsconfig.json └── yarn.lock /.env.example: -------------------------------------------------------------------------------- 1 | NEXT_PUBLIC_COSMIC_BUCKET_SLUG= 2 | NEXT_PUBLIC_COSMIC_READ_KEY= -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files/ for more about ignoring files. 2 | 3 | # dependencies 4 | /node_modules 5 | /.pnp 6 | .pnp.js 7 | 8 | # testing 9 | /coverage 10 | 11 | # next.js 12 | /.next/ 13 | /out/ 14 | 15 | # production 16 | /build 17 | 18 | # misc 19 | .DS_Store 20 | 21 | # debug 22 | npm-debug.log* 23 | yarn-debug.log* 24 | yarn-error.log* 25 | 26 | # local env files 27 | .env.local 28 | .env.development.local 29 | .env.test.local 30 | .env.production.local 31 | .env -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Simple React Blog 2 | ![simple-nextjs-blog](https://github.com/cosmicjs/simple-react-blog/assets/1950722/39a1604a-81a3-4d7d-8276-7650ca626ae1) 3 | 4 | ## NOTE: this repo is now a mirror of the [Simple Next.js Blog](https://github.com/cosmicjs/simple-nextjs-blog) 5 | 6 | 7 | ### [View Demo](https://cosmic-nextjs-blog.vercel.app/) 8 | 9 | ### React + Next.js + Cosmic 10 | This blog uses Next.js to create a React blog. It uses Next.js 13 and the new `app` organization structure which takes advantage of [React Server Components](https://nextjs.org/docs/getting-started/react-essentials#server-components). It connects to the Cosmic API via the [Cosmic JavaScript SDK](https://www.npmjs.com/package/@cosmicjs/sdk). 11 | 12 | ## Getting Started 13 | 1. Log in to Cosmic and install the [Simple Next.js Blog template](https://www.cosmicjs.com/marketplace/templates/simple-nextjs-blog). 14 | 2. Run the following commands to install the code locally. 15 | ``` 16 | git clone https://github.com/cosmicjs/simple-nextjs-blog 17 | cd simple-nextjs-blog 18 | ``` 19 | #### Environment Variables 20 | 21 | 1. Create an `.env.local` file to gain API access to your Cosmic Bucket. To do this, run: 22 | ``` 23 | cp .env.example .env.local 24 | ``` 25 | 2. Find your API access keys at Bucket Settings > API Access after logging into [your Cosmic dashboard](https://app.cosmicjs.com/login) and add them to the `.env.local` file. It should look something like this: 26 | ``` 27 | NEXT_PUBLIC_COSMIC_BUCKET_SLUG=your-bucket-slug 28 | NEXT_PUBLIC_COSMIC_READ_KEY=your-bucket-read-key 29 | ``` 30 | 31 | #### Run in development 32 | Install all dependencies and run in development mode. 33 | ``` 34 | yarn 35 | yarn dev 36 | ``` 37 | Open [http://localhost:3000](http://localhost:3000). 38 | 39 | ## Deploy to Vercel 40 | 41 |

Use the following button to deploy to Vercel. You will need to add API accesss keys as environment variables. Find these in Bucket Settings > API Access.

42 |

43 | 44 |

45 | -------------------------------------------------------------------------------- /app/author/[slug]/page.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import PostCard from '../../../components/PostCard'; 3 | import { getAuthor, getAuthorPosts } from '../../../lib/cosmic'; 4 | 5 | export async function generateMetadata({ params }: { params: { id: string; slug: string } }) { 6 | const author = await getAuthor({ params }); 7 | return { 8 | title: `${author.title} posts | Simple React Blog`, 9 | }; 10 | } 11 | 12 | export default async ({ params }: { params: { id: string; slug: string } }) => { 13 | const author = await getAuthor({ params }); 14 | const posts = await getAuthorPosts({ authorId: author.id }); 15 | 16 | return ( 17 |
18 |

Posts by {author.title}

19 |
20 | {!posts && 'You must add at least one Post to your Bucket'} 21 | {posts && 22 | posts.map((post) => { 23 | return ( 24 |
25 | 26 |
27 | ); 28 | })} 29 |
30 |
31 | ); 32 | }; 33 | -------------------------------------------------------------------------------- /app/layout.tsx: -------------------------------------------------------------------------------- 1 | import React from 'react'; 2 | import '../styles/globals.css'; 3 | import { getGlobalData } from '../lib/cosmic'; 4 | import Generator from 'next/font/local'; 5 | import Banner from '../components/Banner'; 6 | import Header from '../components/Header'; 7 | import Footer from '../components/Footer'; 8 | 9 | const sans = Generator({ 10 | src: '../fonts/Generator-Variable.ttf', 11 | variable: '--font-sans', 12 | }); 13 | 14 | export async function generateMetadata() { 15 | const siteData = await getGlobalData(); 16 | return { 17 | title: siteData.metadata.site_title, 18 | description: siteData.metadata.site_tag, 19 | }; 20 | } 21 | 22 | export default async function RootLayout({ children }: { children: React.ReactNode }) { 23 | const siteData = await getGlobalData(); 24 | 25 | return ( 26 | 27 | 28 | 29 |
30 | {children} 31 |