Convert Jekyll theme to React with Next.js SSG, Tailwind CSS, centralized config, and Markdown parsing
Converts the Jekyll-based theme to React using Next.js with static site generation, server components for optimal SSG, Tailwind CSS styling, centralized configuration, and full Markdown parsing support with Jekyll conventions, maintaining all functionality while modernizing to component-based architecture.
Changes
React Components (replacing Jekyll templates)
-
Layouts:
app/layout.tsx,components/Layout.tsx,components/PostLayout.tsx -
Navigation:
components/Nav.tsxas server component rendering static HTML -
Footer:
components/Footer.tsxas server component rendering static HTML -
Content:
components/MiniBio.tsx,components/ReadingTime.tsx -
Client scripts:
components/ClientScripts.tsxwith dynamic imports for SSR-safe FontAwesome, AnchorJS -
Interactivity:
components/NavbarToggle.tsxfor client-side navbar toggle (simple vanilla JS)
Configuration Management
-
Centralized config:
config/site.tscontains all site configuration- Site name and description
- Navigation pages
- Footer pages
- Repository URL and branch
- All components import from central config instead of hardcoding values
SSG Architecture
- Server components: Nav and Footer render static HTML (no "use client")
-
Minimal client JS: Only 2 components use "use client":
-
NavbarToggle.tsx- handles navbar toggle interactivity only -
ClientScripts.tsx- handles FontAwesome and browser APIs
-
- Progressive enhancement: Works without JS, enhanced with JS for interactivity
- Static HTML generation with Next.js
output: 'export'
Tailwind CSS Styling
- Utility-First CSS: Replaced Bootstrap with Tailwind CSS v3
-
Typography Plugin: Added
@tailwindcss/typographyfor prose content styling -
Dark Mode Support: Built-in dark mode with
dark:variant utilities -
Responsive Design: Mobile-first approach with
sm:,md:,lg:breakpoints - Custom Colors: Preserved primary color (#337ab7) from original theme
- Smaller Bundle: No Bootstrap JavaScript dependencies, only compiled CSS utilities used
-
PostCSS Integration: Configured with
tailwind.config.tsandpostcss.config.js
Markdown Parsing with Jekyll Conventions
- YAML Front Matter: Full support for Jekyll front matter (title, description, archived, tldr, etc.)
-
Post Parsing: Reads posts from
_posts/directory with Jekyll naming convention (YYYY-MM-DD-slug.md) - Page Parsing: Reads markdown pages from root directory
-
Date-based URLs: Generates
/YYYY/MM/DD/slug/URLs for blog posts -
Dynamic Routes:
-
/[year]/[month]/[day]/[slug]/for blog posts -
/about/and/fine-print/for pages - Homepage lists all posts with dates
-
-
Libraries: Uses
gray-matterfor YAML parsing,remarkandremark-htmlfor markdown conversion - Minimal Migration: Existing Jekyll content works as-is with no changes needed
Build Process
- Tailwind CSS compilation via PostCSS
- Next.js native SCSS support for custom styles
- TypeScript excludes legacy
js/script.ts - Simplified build:
npm run build(lint + Next.js SSG)
Before/After
Jekyll:
{% include nav.html %}
{{ content }}
{% include footer.html %}
React with Tailwind:
<Layout hero={true}>
<Nav hero={hero} /> {/* Server component */}
{children}
<Footer /> {/* Server component */}
</Layout>
Styling Before (Bootstrap):
<div className="navbar navbar-expand-md bg-secondary-subtle">
<div className="container-fluid">
<a className="navbar-brand fw-bold">...</a>
</div>
</div>
Styling After (Tailwind):
<nav className="bg-gray-200 dark:bg-gray-800">
<div className="container mx-auto px-3">
<Link className="font-bold text-lg">...</Link>
</div>
</nav>
Screenshots
Desktop with Tailwind CSS:
Mobile (menu expanded with client JS):
Post Page with Parsed Markdown and Tailwind Typography:
Technical Notes
- Tailwind CSS v3 with utility-first approach (no Bootstrap dependencies)
- @tailwindcss/typography plugin for beautiful prose content
- SCSS compilation handled natively by Next.js for custom styles
- Static export generates identical deliverable (HTML/CSS/JS in
out/) - No server runtime required
- Server components for content, client components only for interactivity
- Perfect SSG: all content pre-rendered in static HTML
- Dark mode support with automatic color scheme detection
- Markdown parsing with Jekyll conventions - zero content migration needed
- Development:
npm run dev| Production:npm run build
Original prompt
This section details on the original issue you should resolve
<issue_title>Convert to react</issue_title> <issue_description>Both the HTML/CSS and the JS.</issue_description>
Comments on the Issue (you are @copilot in this section)
- Fixes benbalter/retlab#640
✨ Let Copilot coding agent set things up for you — coding agent works faster and does higher quality work when set up for your repo.