A modern, responsive blog application built with Next.js 14 that serves content from local markdown files. This project serves as the frontend for oriol.im, featuring a glassmorphism design with Spanish localization.
- Local Markdown Content: Posts and pages served from local markdown files
- Modern Design: Glassmorphism UI with backdrop blur effects
- Responsive Layout: Mobile-first design with floating navigation menu
- Dynamic Routing: Automatic page generation for posts and pages
- TypeScript: Full type safety with content entity definitions
- SEO Optimized: Server-side rendering with Next.js App Router
- Image Optimization: Next.js Image component with local static images
- Syntax Highlighting: Prism.js integration for code blocks
- Frontend: Next.js 14, React 18, TypeScript
- Styling: TailwindCSS with custom glassmorphism effects
- Content: Local Markdown files with Gray Matter frontmatter
- HTTP Client: Native fetch API
- Icons: Lucide React
- Image Handling: Next.js Image with local static files
- Node.js 18+
- npm or yarn
- Clone the repository:
git clone https://github.com/your-username/oriol-im.git
cd oriol-im- Install dependencies:
npm install- Set up environment variables (optional):
# Copy the example environment file (create one if needed)
cp .env.example .env.localConfigure the following environment variables:
NEXT_PUBLIC_SITE_URL=https://your-domain.com
NEXT_PUBLIC_SITE_TITLE=Your Site Title
NEXT_PUBLIC_SITE_DESCRIPTION=Your site description
NEXT_PUBLIC_CONTACT_FORM_URL=https://your-contact-form-endpoint.com- Run the development server:
npm run dev- Open http://localhost:3000 in your browser.
- Create a new markdown file in the
posts/directory - Follow the naming convention:
YYYY-MM-DD-slug.md - Add frontmatter with required fields:
---
title: "Your Post Title"
slug: "your-post-slug"
date: "2024-01-01"
excerpt: "Post excerpt here"
status: "publish"
type: "post"
id: "unique-id"
categories:
- "Category 1"
- "Category 2"
tags:
- "tag1"
- "tag2"
---
Your post content here...- Create a new markdown file in the
pages/directory - Name it after the slug:
page-slug.md - Add frontmatter with required fields:
---
title: "Your Page Title"
slug: "page-slug"
date: "2024-01-01"
modified: "2024-01-01"
excerpt: "Page excerpt here"
status: "publish"
type: "page"
id: "unique-id"
parent: 0
menu_order: 0
---
Your page content here...npm run dev- Start development servernpm run build- Build for productionnpm run start- Start production servernpm run lint- Run ESLintnpm run type-check- Run TypeScript type checking
src/
├── app/ # Next.js App Router pages
│ ├── [slug]/ # Dynamic routes for posts and pages
│ ├── about/ # About page
│ ├── blog/ # Blog listing page
│ ├── contact/ # Contact page
│ ├── api/ # API routes
│ │ ├── posts/ # Posts API endpoints
│ │ └── pages/ # Pages API endpoints
│ ├── globals.css # Global styles
│ ├── layout.tsx # Root layout component
│ └── page.tsx # Homepage
├── components/ # Reusable React components
│ ├── Footer.tsx
│ ├── Header.tsx
│ ├── PostCard.tsx
│ └── ReadingProgress.tsx
├── lib/ # Utility functions and configuration
│ ├── config.ts # Environment configuration
│ ├── markdown.ts # Server-side markdown parsing for posts
│ ├── pages-markdown.ts # Server-side markdown parsing for pages
│ ├── posts.ts # Client-side posts API
│ ├── pages.ts # Client-side pages API
│ └── utils.ts # Utility functions
├── types/ # TypeScript type definitions
│ ├── post.ts # Post entity types
│ └── page.ts # Page entity types
posts/ # Markdown blog posts
pages/ # Markdown pages
└── public/
└── images/ # Static images
The application serves content through a dual-layer system:
Server-side parsing:
src/lib/markdown.ts- Parses post markdown filessrc/lib/pages-markdown.ts- Parses page markdown files
Client-side API:
src/lib/posts.ts- Client-side posts interfacesrc/lib/pages.ts- Client-side pages interface/api/posts/and/api/pages/- REST API endpoints
All content entities are fully typed with TypeScript interfaces.
The project uses TailwindCSS with custom configurations:
- Glassmorphism effects: Backdrop blur with gradient backgrounds
- Custom typography: Extended prose styles for markdown content
- Responsive design: Mobile-first approach with breakpoint utilities
- Custom animations: CSS keyframes for UI interactions
npm run build
npm run start- Push your code to GitHub
- Connect your repository to Vercel
- Configure environment variables in Vercel dashboard (optional)
- Deploy automatically on every push
The application can be deployed to any platform that supports Node.js:
- Netlify: Configure build command as
npm run build - Railway: Connect GitHub repository and deploy
- DigitalOcean App Platform: Use Node.js buildpack
Key configurations in next.config.mjs:
- App Directory: App router enabled
- Image Optimization: Configured for local images
- API Routes: RESTful endpoints for content
- Posts: Stored in
/posts/directory as markdown files - Pages: Stored in
/pages/directory as markdown files - Images: Static images in
/public/images/ - Metadata: Frontmatter-based with Gray Matter parsing
This project was migrated from a WordPress-based architecture. Migration scripts are available in /scripts/ for reference, but the application now runs entirely on local markdown files for improved performance and maintainability.
- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
This project is licensed under the MIT License - see the LICENSE file for details.
- Website: oriol.im
- Email: Contact through the website form
- GitHub: @OriolEgea
Built with ❤️ using Next.js and Markdown