A production-ready Next.js 14 blog powered by Hashnode as a headless CMS via GraphQL.
GitHub: brightafam45/digitalnerdhq-blog
- Framework: Next.js 14 (App Router, TypeScript)
- CMS: Hashnode (headless via GraphQL)
- Styling: Tailwind CSS
- Fonts: Inter (Google Fonts)
- Deployment: Vercel
git clone https://github.com/brightafam45/digitalnerdhq-blog.git
cd digitalnerdhq-blogcp .env.example .env.localOpen .env.local and fill in your values:
HASHNODE_API_KEY=your_hashnode_api_key_here
HASHNODE_HOST=yourpublication.hashnode.dev
NEXT_PUBLIC_SITE_URL=https://your-blog-domain.comNote: Never commit
.env.localto version control. It is listed in.gitignore.
Get your Hashnode API key from: hashnode.com/settings/developer
npm installnpm run devOpen http://localhost:3000 in your browser.
digitalnerdhq-blog/
├── app/
│ ├── layout.tsx # Root layout (Header, Footer, NewsletterPopup)
│ ├── page.tsx # Homepage
│ ├── globals.css # Global styles + article content styles
│ ├── blog/
│ │ ├── page.tsx # All articles listing
│ │ └── [slug]/
│ │ └── page.tsx # Single article page
│ └── tags/
│ ├── page.tsx # All topics index
│ └── [slug]/
│ └── page.tsx # Tag archive page
├── components/
│ ├── Header.tsx # Sticky header with mobile nav
│ ├── Footer.tsx # Footer with newsletter
│ ├── FeaturedPost.tsx # Hero featured post
│ ├── PostCard.tsx # Post card (default, large, compact)
│ ├── TagBadge.tsx # Tag pill badge
│ ├── NewsletterPopup.tsx # Exit-intent newsletter popup
│ ├── NewsletterInline.tsx # Inline newsletter section
│ ├── ArticleContent.tsx # Safe HTML renderer for articles
│ ├── ReadingProgress.tsx # Scroll-based reading progress bar
│ └── ShareButtons.tsx # Twitter, LinkedIn, Copy Link
├── lib/
│ └── hashnode.ts # Hashnode GraphQL client + queries
├── types/
│ └── index.ts # TypeScript types
├── .env.example # Example environment variables
├── .env.local # Your secrets (not committed)
├── next.config.ts
├── tailwind.config.ts
├── tsconfig.json
└── vercel.json
- Push your code to GitHub
- Go to vercel.com/new and import your repository
- Add environment variables in the Vercel dashboard:
HASHNODE_API_KEYHASHNODE_HOSTNEXT_PUBLIC_SITE_URL
- Deploy!
Or use the one-click deploy button at the top of this README.
The newsletter popup and inline forms currently use a simulated submit. To connect a real email provider:
- Open
components/NewsletterPopup.tsxandcomponents/NewsletterInline.tsx - Replace the simulated delay with a real API call:
// Example with Resend / ConvertKit / Mailchimp
await fetch('/api/subscribe', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ email }),
})- Create
app/api/subscribe/route.tswith your email provider's SDK.
MIT — feel free to use this as a starter for your own Hashnode-powered blog.