An open API service indexing awesome lists of open source software.

https://github.com/amirardalan/amirardalan.com

A Markdown blog and CMS written in TypeScript using Next.js App Router. Publish and edit blog posts without a build using On-demand Revalidation.
https://github.com/amirardalan/amirardalan.com

authjs clsx dark-mode google-fonts nextjs ogimage-nextjs react supabase tailwindcss upstash-redis zustand

Last synced: about 1 month ago
JSON representation

A Markdown blog and CMS written in TypeScript using Next.js App Router. Publish and edit blog posts without a build using On-demand Revalidation.

Awesome Lists containing this project

README

          

# amirardalan.com

Amir Ardalan's personal website built with [Startup](https://github.com/amirardalan/startup). This is a Markdown Blog and CMS written in TypeScript leveraging React Server Components. Create, edit, and manage blog posts and categories inside a custom CMS. Update static posts without a build leveraging the power of on-demand revalidation.

### Stack

- TypeScript
- [Next.js](https://nextjs.org/docs/getting-started) App Router
- [Auth.js](https://authjs.dev/) auth
- [Tailwind CSS](https://tailwindcss.com/docs/installation) styles
- [Supabase](https://supabase.com/docs/guides/database/overview) Postgres database
- [Drizzle ORM](https://orm.drizzle.team/) for Postgres
- [MDX](https://mdxjs.com/) Markdown
- [Sugar High](https://github.com/huozhi/sugar-high) syntax highlighting
- [Zustand](https://github.com/pmndrs/zustand) state management
- [CLSX](https://github.com/lukeed/clsx) `className` logic

### Features

- Custom CMS (Publish, Edit, Manage Drafts and Categories)
- Light/Dark/System Theme toggle
- Dynamic (theme-based) favicon
- Dynamic Metadata and Page Titles
- Route-based active navigation highlighting
- Dynamic footer copyright date
- Custom Tooltip, Modal, and Toast components
- Next.js [optimized fonts](https://nextjs.org/learn/dashboard-app/optimizing-fonts-images)
- [OG Image](https://vercel.com/docs/functions/og-image-generation) metadata
- Dynamically-generated [sitemap.xml](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap)
- Custom [Cloudinary](https://cloudinary.com/) CMS Media Gallery
- [PostHog](https://posthog.com/) analytics and blog post view count
- Blog likes with [Upstash](https://upstash.com/) Redis
- Accessibility, perfomance, and SEO best-practices
- 100% Lighthouse score

## Getting Started

### Setup

```bash
npm install
```

Then, set up your [GitHub oAuth App](https://authjs.dev/getting-started/providers/github?framework=next-js) and add your GitHub Client ID and Secret in a `.env.local` file:

```
// .env.local

# Set for each environment
NEXT_PUBLIC_URL="http://localhost:3000"

# Set your timezone
NEXT_PUBLIC_TIMEZONE="America/Los_Angeles"

# Resume Link (redirect in next.config.ts)
RESUME_URL=

# Auth.js
AUTH_SECRET=
AUTH_TRUST_HOST="NEXT_PUBLIC_URL"

# GitHub OAuth
AUTH_GITHUB_ID=
AUTH_GITHUB_SECRET=

# Email verification (CMS Users)
ALLOWED_EMAILS=
ALLOWED_EMAIL_DOMAINS=

# Supabase (CMS Database)
DB_URL=
DB_API_KEY=

# Cloudinary (CMS Media Gallery)
NEXT_PUBLIC_CLOUDINARY_CLOUD_NAME=
CLOUDINARY_URL=
CLOUDINARY_API_KEY=
CLOUDINARY_API_SECRET=

# PostHog (Analytics)
NEXT_PUBLIC_POSTHOG_KEY=
NEXT_PUBLIC_POSTHOG_HOST=
POSTHOG_API_KEY=
POSTHOG_PROJECT_ID=

# Upstash/Redis (Blog Likes)
ENABLE_DEV_CACHE="true"
KV_URL=
KV_REST_API_READ_ONLY_TOKEN=
REDIS_URL=
KV_REST_API_TOKEN=
KV_REST_API_URL=
```

And finally, generate a Next Auth secret which will automatically overwrite the placeholder in the `.env.local` file:

```bash
npx auth secret
```

### Database

```bash
npx drizzle-kit push
```

> [!NOTE]
> This command will create the database tables and columns based on the schema defined in `./src/db/schema.ts` file.

### Run

```bash
npm run dev
```

### Preview

To test On-demand Revalidation of blog posts and to ensure the app is in good shape to run on production it is recommended to compile a preview build.

```bash
npm run preview
```

> [!NOTE]
> This script will format the project using Prettier, check linting, and then compile a preview build.

### Drizzle Studio

To interact with the postgres database locally:

```bash
npx drizzle-kit studio
```

> [!NOTE]
> If using Brave browser you must turn Brave Shield off for `https://local.drizzle.studio/`

### Markdown Features

#### Images

Blog posts are written in Markdown. Markdown images will utilize the Next Image component for optimized loading. The markdown image can be passed a priority prop:

```markdown
![Alt text](https://example.com/image.png 'priority')
```

Or you can use an image wrapped in a custom MDX `` component to add a caption (this also works with an optional priority prop for images above the fold):

```markdown

```

#### Code

Highlight individual lines or blocks of code (line 2 and lines 3-5):

````
```typescript{2,3-5}
````