Website Link: Demo Live Site
Total time spent on this project:
100+ hours on WakaTime. Every page, route, component, API endpoint, email template — no dead links, no unfinished sections. Custom 404, Coming Soon page, full newsletter pipeline. Learning project, shipped complete.
Fyrre Magazine is a digital magazine platform built with Next.js 16. MDX articles with frontmatter, category filtering via URL params, pagination that resets when you switch categories — the usual content-site essentials. Newsletter subscriptions go through Resend with React Email templates. Also includes a podcast section, author profiles, and a custom 404 page.
Design by Pawel Gola.
- MDX format article support with frontmatter parsing
- Magazine category filtering with URL search params (
?category=sculptures) - URL-synced Prev / Next pagination — 6 articles per page (
?page=2) - Pagination resets to page 1 automatically when changing category
- Custom author profiles and integrated podcast section
- Form validation with react-hook-form + Zod on both client and server
- Resend email delivery API integration
- Subscribers automatically saved to Resend Audiences — works without a verified domain
- Demo mode — welcome emails redirected to a test address (
RESEND_TEST_EMAIL) - Production mode — welcome emails sent directly to subscribers (
RESEND_FROM_EMAIL) - Admin notification email on every new subscription
- Animated Toast notifications with auto-dismiss progress bar
- Reusable Spinner component for loading states
WelcomeEmail— welcome email sent to new subscribersAdminNotificationEmail— instant admin notification with subscriber details- Design tokens fully synchronized with
globals.css(colors, spacing, typography)
- Responsive layout across all devices
- Keyboard navigation and screen reader support (
VisuallyHidden,aria-*,role) - SEO optimized with dynamic metadata per page
- Optimized image loading with Next.js
Imagecomponent - Smooth little animations powered by Motion
- Next.js 16 — React framework with App Router & Webpack
- React 19 — UI library
- TypeScript 5 — Static typing
- Tailwind CSS 4 — Utility-first CSS framework
- CVA — Component variant management (
cva@1.0.0-beta) - tailwind-merge — Tailwind class merging
- @radix-ui/react-slot — Accessible UI primitives
- clsx — Conditional class building
- Motion 12 — Animation library
- lucide-react — Icon library
- MDX — Enhanced Markdown with JSX
- gray-matter — Frontmatter parsing
- next-mdx-remote 6 — MDX rendering
- date-fns 4 — Date manipulation
- react-hook-form 7 — Performant form management
- Zod 4 — Schema validation (client & server)
- @hookform/resolvers 5 — Zod adapter
- Resend 6 — Email delivery API
- React Email 5 — React-based email template components
- @react-email/components — Email UI primitives
- react-focus-lock — Focus management
- Node.js 18+
- Bun (package manager)
- A Resend account (free tier is sufficient)
# Clone the repository
git clone https://github.com/souleymanesy7/fyrre-magazine-website.git
# Navigate to directory
cd fyrre-magazine-website
# Install dependencies
bun install
# Start development server
bun run devCreate a .env.local file at the root of the project:
# ── Required ──────────────────────────────────────────────────────────────────
# Resend API key — get yours at resend.com
RESEND_API_KEY=re_xxxxxxxxxxxxxxxxxx
# Admin email — receives a notification on every new subscriber
NEWSLETTER_TO_EMAIL=your@email.com
# ── Email sending mode (pick one) ─────────────────────────────────────────────
# Demo mode — welcome emails are redirected to this address instead of the real subscriber
# Use this when you don't have a verified domain yet
RESEND_TEST_EMAIL=your@email.com
# Production mode — set this once your domain is verified at resend.com/domains
# When defined, welcome emails are sent directly to the real subscriber
# RESEND_FROM_EMAIL=hello@your-domain.comHow it works without a verified domain: Resend's free plan only allows sending emails to your own account address. With
RESEND_TEST_EMAILset, welcome emails are redirected to you for preview — while every subscriber's email is still saved in your Resend Audience list. When you add a verified domain, just setRESEND_FROM_EMAILand removeRESEND_TEST_EMAIL. No code changes required.
fyrre-magazine-website/
├── contents/ # MDX content files
│ ├── magazine/ # Magazine articles
│ ├── authors/ # Author profiles
│ └── podcast/ # Podcast episodes
│
├── public/ # Static assets
│ ├── assets/ # Images and media
│ └── preview/ # README preview images
│
├── src/
│ ├── app/ # Next.js App Router
│ │ ├── api/
│ │ │ └── newsletter/ # POST /api/newsletter — Resend integration
│ │ ├── authors/ # Authors listing + individual pages
│ │ ├── coming-soon/ # Dedicated coming soon page for unavailable links
│ │ ├── magazine/ # Magazine listing — category filter + pagination
│ │ ├── podcast/ # Podcast listing + individual episodes
│ │ ├── style-guide/ # Internal design system reference
│ │ ├── favicon.ico
│ │ ├── globals.css # Global styles & design tokens
│ │ ├── layout.tsx # Root layout
│ │ ├── not-found.tsx # Custom 404 page
│ │ └── page.tsx # Homepage
│ │
│ ├── components/
│ │ ├── common/ # Reusable UI primitives
│ │ │ ├── Button.tsx
│ │ │ ├── Card.tsx
│ │ │ ├── Container.tsx
│ │ │ ├── Form.tsx
│ │ │ ├── Input.tsx
│ │ │ ├── List.tsx
│ │ │ ├── SkipToContents.tsx
│ │ │ ├── Title.tsx
│ │ │ └── VisuallyHidden.tsx
│ │ ├── ui/ # Reusable UI components
│ │ │ ├── DateFormatter.tsx
│ │ │ ├── Headline.tsx
│ │ │ ├── LinkWithArrow.tsx
│ │ │ ├── Marquee.tsx
│ │ │ ├── Pagination.tsx # Prev/Next navigation with URL sync
│ │ │ ├── PrintEditionCard.tsx # Cover card with hover overlay + coming soon CTA
│ │ │ ├── ScrollIndicator.tsx
│ │ │ ├── Spinner.tsx # Animated 4-bar loading indicator
│ │ │ └── Toast.tsx # Slide-up notification with progress bar
│ │ ├── navigation/ # Navigation components
│ │ │ ├── Footer.tsx
│ │ │ ├── HamburgerMenu.tsx
│ │ │ ├── Header.tsx
│ │ │ ├── Navbar.tsx
│ │ │ ├── NavbarDesktop.tsx
│ │ │ ├── NavbarMobile.tsx
│ │ │ └── SingleNav.tsx
│ │ ├── sections/ # Page section components
│ │ │ ├── homepage/
│ │ │ │ ├── HomepageAuthorList.tsx
│ │ │ │ ├── HomepageHero.tsx
│ │ │ │ ├── HomepageMagazineList.tsx
│ │ │ │ ├── HomepagePodcastList.tsx
│ │ │ │ └── HomepageSidebar.tsx
│ │ │ ├── magazine/
│ │ │ │ ├── MagazineCategories.tsx # Category filter with URL sync
│ │ │ │ ├── MagazineLatestArticles.tsx
│ │ │ │ ├── MagazinePostContents.tsx
│ │ │ │ ├── MagazinePostHero.tsx
│ │ │ │ ├── MagazinePostSidebar.tsx
│ │ │ │ ├── MagazineSummaryCard.tsx
│ │ │ │ └── Magazines.tsx # Magazine grid with filter + pagination
│ │ │ ├── authors/
│ │ │ │ ├── AuthorContents.tsx
│ │ │ │ ├── AuthorSideBar.tsx
│ │ │ │ └── AuthorSummaryCard.tsx
│ │ │ └── podcast/
│ │ │ ├── PodcastContents.tsx
│ │ │ ├── PodcastSidebar.tsx
│ │ │ └── PodcastSummaryCard.tsx
│ │ ├── forms/ # Form components
│ │ │ └── NewsletterForm.tsx # Unified form — footer & sidebar variants
│ │ └── errors/ # Error & fallback pages
│ │ └── Custom404.tsx
│ │
│ ├── emails/ # React Email templates
│ │ ├── WelcomeEmail/
│ │ │ ├── WelcomeEmail.tsx
│ │ │ └── style.ts # Design tokens mirrored from globals.css
│ │ └── AdminNotificationEmail/
│ │ ├── AdminNotificationEmail.tsx
│ │ └── style.ts # Design tokens mirrored from globals.css
│ │
│ ├── hooks/
│ │ └── usePagination.ts # Client-side pagination with URL search params
│ │
│ ├── constants/ # Static data and configuration
│ ├── libs/ # Utility functions and helpers
│ ├── icons/ # SVG icon components
│ ├── types/ # TypeScript type definitions
│ └── validators/ # Zod schemas (email, forms)
│
├── .gitignore
├── bun.lock
├── eslint.config.mjs
├── next.config.ts # Next.js & Webpack configuration
├── postcss.config.mjs # PostCSS configuration for Tailwind
├── tsconfig.json # TypeScript configuration
└── package.json
Preview your email templates locally with React Email:
bunx email dev --dir src/emailsOpens a live preview server at http://localhost:3000 with hot reload for all email templates.
- Lighthouse Score:
- Performance: 97/100
- Accessibility: 100/100
- Best Practices: 100/100
- SEO: 100/100
bun run dev # Start development server with Webpack
bun run build # Build for production + copy MDX contents to .next/standalone
bun run start # Start production server
bun run lint # Run ESLintnext.config.ts— Next.js and Webpack configurationtsconfig.json— TypeScript configuration.env.local— Environment variables (see above)
Contributions are welcome! Please follow these steps:
- Fork the project
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
Developed with ❤️ by Souleymane Sy

