├── .gitignore ├── .vscode └── settings.json ├── README.md ├── app ├── (admin) │ ├── head.tsx │ ├── layout.tsx │ └── studio │ │ └── [[...index]] │ │ ├── head.tsx │ │ ├── loading.tsx │ │ └── page.tsx ├── (user) │ ├── layout.tsx │ ├── page.tsx │ └── post │ │ └── [slug] │ │ └── page.tsx └── head.tsx ├── components ├── Banner.tsx ├── BlogList.tsx ├── ClientSideRoute.tsx ├── DarkModeButton.tsx ├── Footer.tsx ├── Header.tsx ├── Logo.tsx ├── PostCard.tsx ├── PreviewBlogList.tsx ├── PreviewSuspense.tsx ├── Providers.tsx ├── RichTextComponents.tsx ├── ScrollToTop.tsx └── StudioNavbar.tsx ├── lib ├── sanity.client.ts ├── sanity.preview.ts └── urlFor.ts ├── next.config.js ├── package.json ├── pages └── api │ ├── exit-preview.ts │ └── preview.ts ├── postcss.config.js ├── public ├── cover.png ├── favicon.ico └── vercel.svg ├── sanity.cli.ts ├── sanity.config.ts ├── schemas ├── author.ts ├── blockContent.ts ├── category.ts ├── index.ts └── post.ts ├── structure.ts ├── styles └── globals.css ├── tailwind.config.js ├── theme.ts ├── tsconfig.json ├── typings.d.ts └── yarn.lock /.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 | *.pem 21 | 22 | # debug 23 | npm-debug.log* 24 | yarn-debug.log* 25 | yarn-error.log* 26 | .pnpm-debug.log* 27 | 28 | # local env files 29 | .env*.local 30 | 31 | # vercel 32 | .vercel 33 | 34 | # typescript 35 | *.tsbuildinfo 36 | next-env.d.ts -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "typescript.tsdk": "node_modules/typescript/lib", 3 | "typescript.enablePromptUseWorkspaceTsdk": true 4 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # NextJS-Sanity-Blog 2 | 3 | For this project I built a Blog with Next.js 13 (Sanity v3, TypeScript, Tailwind CSS, Auth, CMS, Preview Mode) and Vercel for deployment. 4 | 5 | ## Screen 6 | 7 | ![](public/cover.png) 8 | 9 | ## Link 10 | 11 | - [NextJS Blog](https://adperformance-blog.vercel.app/) 12 | 13 | ### Next.js + Tailwind CSS Example 14 | 15 | This example shows how to use [Tailwind CSS](https://tailwindcss.com/) [(v3.2)](https://tailwindcss.com/blog/tailwindcss-v3-2) with Next.js. It follows the steps outlined in the official [Tailwind docs](https://tailwindcss.com/docs/guides/nextjs). 16 | 17 | ### Deploy your own 18 | 19 | Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-tailwindcss) 20 | 21 | [![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-tailwindcss&project-name=with-tailwindcss&repository-name=with-tailwindcss) 22 | 23 | ### How to use 24 | 25 | Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example: 26 | 27 | ```bash 28 | npx create-next-app --example with-tailwindcss with-tailwindcss-app 29 | ``` 30 | 31 | ```bash 32 | yarn create next-app --example with-tailwindcss with-tailwindcss-app 33 | ``` 34 | 35 | ```bash 36 | pnpm create next-app --example with-tailwindcss with-tailwindcss-app 37 | ``` 38 | 39 | Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)). 40 | -------------------------------------------------------------------------------- /app/(admin)/head.tsx: -------------------------------------------------------------------------------- 1 | export default function Head() { 2 | return ( 3 | <> 4 | 5 | 6 | 7 | 8 | ) 9 | } 10 | -------------------------------------------------------------------------------- /app/(admin)/layout.tsx: -------------------------------------------------------------------------------- 1 | import "../../styles/globals.css"; 2 | 3 | export default function RootLayout({ 4 | children, 5 | }: { 6 | children: React.ReactNode; 7 | }) { 8 | return ( 9 | 10 | {children} 11 | 12 | ); 13 | } 14 | -------------------------------------------------------------------------------- /app/(admin)/studio/[[...index]]/head.tsx: -------------------------------------------------------------------------------- 1 | // Re-export `NextStudioHead` as default if you're happy with the default behavior 2 | export { NextStudioHead } from "next-sanity/studio/head"; 3 | 4 | // To customize it, use it as a children component: 5 | import { NextStudioHead } from "next-sanity/studio/head"; 6 | 7 | export default function CustomStudioHead() { 8 | return ( 9 | <> 10 | 11 | CMS 12 | 18 | 19 | ); 20 | } 21 | -------------------------------------------------------------------------------- /app/(admin)/studio/[[...index]]/loading.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import config from "../../../../sanity.config"; 4 | import NextStudioLoading from "next-sanity/studio/loading"; 5 | 6 | export default function Loading() { 7 | return ; 8 | } 9 | -------------------------------------------------------------------------------- /app/(admin)/studio/[[...index]]/page.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { NextStudio } from "next-sanity/studio"; 4 | 5 | import config from "../../../../sanity.config"; 6 | 7 | export default function StudioPage() { 8 | // Supports the same props as `import {Studio} from 'sanity'`, `config` is required 9 | return ; 10 | } 11 | -------------------------------------------------------------------------------- /app/(user)/layout.tsx: -------------------------------------------------------------------------------- 1 | "use client"; 2 | 3 | import { usePathname } from "next/navigation"; 4 | import Banner from "../../components/Banner"; 5 | import Footer from "../../components/Footer"; 6 | import Header from "../../components/Header"; 7 | import ScrollToTop from "../../components/ScrollToTop"; 8 | 9 | import Providers from "../../components/Providers"; 10 | 11 | import "../../styles/globals.css"; 12 | 13 | export default function RootLayout({ 14 | children, 15 | }: { 16 | children: React.ReactNode; 17 | }) { 18 | const router = usePathname(); 19 | const hideBanner = router?.startsWith("/post/") ? false : true; 20 | return ( 21 | 22 | 23 | 24 |
25 | 26 | {hideBanner && } 27 | {children} 28 |