"use client" import fs from "fs" import path from "path" import matter from "gray-matter" const postsDirectory = path.join(process.cwd(), "posts") export interface PostMetadata { title: string date: string excerpt: string [key: string]: any } export interface Post { slug: string content: string metadata: PostMetadata } // Create posts directory if it doesn't exist try { if (!fs.existsSync(postsDirectory)) { fs.mkdirSync(postsDirectory, { recursive: true }) createSamplePosts() } } catch (error) { console.error("Error checking or creating posts directory:", error) } // Changed to synchronous to avoid suspense issues export function getAllPosts(): Post[] { try { const filenames = fs.readdirSync(postsDirectory) const posts = filenames .filter((filename) => filename.endsWith(".md")) .map((filename) => { const slug = filename.replace(/\.md$/, "") const fullPath = path.join(postsDirectory, filename) const fileContents = fs.readFileSync(fullPath, "utf8") const { data, content } = matter(fileContents) return { slug, content, metadata: data as PostMetadata, } }) return posts } catch (error) { console.error("Error getting all posts:", error) return [] } } // Changed to synchronous to avoid suspense issues export function getPostBySlug(slug: string): Post | null { try { const fullPath = path.join(postsDirectory, `${slug}.md`) const fileContents = fs.readFileSync(fullPath, "utf8") const { data, content } = matter(fileContents) return { slug, content, metadata: data as PostMetadata, } } catch (error) { console.error(`Error getting post by slug ${slug}:`, error) return null } } function createSamplePosts() { const samplePosts = [ { filename: "getting-started-with-nextjs.md", content: `--- title: "Getting Started with Next.js" date: "2023-05-15" excerpt: "Learn how to build modern web applications with Next.js" --- # Getting Started with Next.js Next.js is a React framework that enables functionality such as server-side rendering and static site generation. ## Why Next.js? - **Server-side Rendering**: Improves performance and SEO - **Static Site Generation**: Pre-renders pages at build time - **API Routes**: Build API endpoints as part of your Next.js app - **File-based Routing**: Create routes based on your file structure ## Getting Started To create a new Next.js app, run: \`\`\`bash npx create-next-app@latest my-app \`\`\` This will set up everything automatically for you.`, }, { filename: "markdown-styling-guide.md", content: `--- title: "Markdown Styling Guide" date: "2023-06-22" excerpt: "Learn how to style your markdown content for better readability" --- # Markdown Styling Guide Markdown is a lightweight markup language that you can use to add formatting elements to plaintext text documents. ## Basic Syntax ### Headers # H1 ## H2 ### H3 ### Emphasis *This text will be italic* _This will also be italic_ **This text will be bold** __This will also be bold__ ### Lists Unordered: - Item 1 - Item 2 - Item 2a - Item 2b Ordered: 1. Item 1 2. Item 2 3. Item 3 ### Links [GitHub](http://github.com) ### Images ![Alt Text](https://via.placeholder.com/150) ### Code Inline \`code\` has \`back-ticks around\` it. \`\`\`javascript var s = "JavaScript syntax highlighting"; alert(s); \`\`\``, }, { filename: "building-accessible-websites.md", content: `--- title: "Building Accessible Websites" date: "2023-07-10" excerpt: "Learn how to make your websites accessible to everyone" --- # Building Accessible Websites Web accessibility means that websites, tools, and technologies are designed and developed so that people with disabilities can use them. ## Why Accessibility Matters - **Inclusivity**: Everyone should be able to access and use web content - **Legal Requirements**: Many countries have laws requiring web accessibility - **Better UX**: Accessible sites often provide better user experience for everyone - **SEO Benefits**: Many accessibility practices improve SEO ## Key Accessibility Practices ### Semantic HTML Use the right HTML elements for their intended purpose: \`\`\`html
Submit
\`\`\` ### Keyboard Navigation Ensure all interactive elements are keyboard accessible: - Use proper focus states - Maintain a logical tab order - Provide skip links ### Alternative Text Always provide alt text for images: \`\`\`html Bar chart showing sales data for Q1 2023 \`\`\``, }, // Adding 5 more dummy posts { filename: "modern-css-techniques.md", content: `--- title: "Modern CSS Techniques for 2023" date: "2023-08-05" excerpt: "Explore the latest CSS features and techniques that are changing web development" --- # Modern CSS Techniques for 2023 CSS has evolved significantly in recent years, with powerful new features that make complex layouts and effects easier than ever. ## CSS Grid CSS Grid has revolutionized web layouts: \`\`\`css .container { display: grid; grid-template-columns: repeat(auto-fill, minmax(250px, 1fr)); gap: 1rem; } \`\`\` ## CSS Custom Properties (Variables) Variables make your CSS more maintainable: \`\`\`css :root { --primary-color: #3490dc; --secondary-color: #ffed4a; } .button { background-color: var(--primary-color); } \`\`\` ## Container Queries Container queries allow you to style elements based on their parent container's size: \`\`\`css @container (min-width: 700px) { .card { display: grid; grid-template-columns: 2fr 1fr; } } \`\`\` ## Logical Properties Logical properties make internationalization easier: \`\`\`css .element { margin-inline: 1rem; padding-block: 0.5rem; } \`\`\` ## Conclusion Modern CSS is more powerful than ever, enabling developers to create complex layouts and effects with less code and greater flexibility.`, }, { filename: "typescript-best-practices.md", content: `--- title: "TypeScript Best Practices for Large Projects" date: "2023-08-12" excerpt: "Learn how to effectively use TypeScript in large-scale applications" --- # TypeScript Best Practices for Large Projects TypeScript has become the standard for large-scale JavaScript applications. Here are some best practices to keep your codebase maintainable. ## Type Everything Always define types for your data structures: \`\`\`typescript interface User { id: string; name: string; email: string; role: 'admin' | 'user' | 'guest'; preferences?: UserPreferences; } // Instead of: // const user = { id: '123', name: 'John' }; \`\`\` ## Use Discriminated Unions Discriminated unions make your code more type-safe: \`\`\`typescript type Success = { status: 'success'; data: User[]; }; type Error = { status: 'error'; message: string; }; type ApiResponse = Success | Error; function handleResponse(response: ApiResponse) { if (response.status === 'success') { // TypeScript knows response.data exists return response.data; } else { // TypeScript knows response.message exists throw new Error(response.message); } } \`\`\` ## Avoid Any The \`any\` type defeats the purpose of TypeScript. Use \`unknown\` instead when necessary: \`\`\`typescript // Bad function parseData(data: any) { return data.items; } // Good function parseData(data: unknown) { if (typeof data === 'object' && data !== null && 'items' in data) { return (data as { items: unknown[] }).items; } throw new Error('Invalid data format'); } \`\`\` ## Conclusion Following these best practices will help you build more maintainable and robust TypeScript applications.`, }, { filename: "serverless-architecture.md", content: `--- title: "Introduction to Serverless Architecture" date: "2023-08-20" excerpt: "Understand the benefits and challenges of serverless computing" --- # Introduction to Serverless Architecture Serverless computing allows developers to build and run applications without thinking about servers. ## What is Serverless? Despite the name, serverless doesn't mean there are no servers. It means you don't have to manage them: - No provisioning servers - No worrying about scaling - Pay only for what you use - Focus on code, not infrastructure ## Key Serverless Services ### AWS Lambda \`\`\`javascript exports.handler = async (event) => { const result = await processData(event.data); return { statusCode: 200, body: JSON.stringify(result) }; }; \`\`\` ### Azure Functions \`\`\`javascript module.exports = async function (context, req) { const result = await processData(req.body); context.res = { status: 200, body: result }; }; \`\`\` ## Challenges Serverless isn't perfect for every use case: - Cold starts can impact performance - Long-running processes aren't ideal - Debugging can be more difficult - Vendor lock-in concerns ## Conclusion Serverless architecture can significantly reduce operational complexity and cost for many applications, but it's important to understand its limitations and use cases.`, }, { filename: "react-performance-optimization.md", content: `--- title: "React Performance Optimization Techniques" date: "2023-08-25" excerpt: "Learn how to make your React applications faster and more efficient" --- # React Performance Optimization Techniques Performance optimization is crucial for providing a good user experience in React applications. ## Use React.memo for Component Memoization Prevent unnecessary re-renders with React.memo: \`\`\`jsx const ExpensiveComponent = React.memo(({ data }) => { // Render using data return
{/* ... */}
; }); \`\`\` ## Virtualize Long Lists Use virtualization for long lists: \`\`\`jsx import { FixedSizeList } from 'react-window'; function VirtualizedList({ items }) { const Row = ({ index, style }) => (
{items[index].name}
); return ( {Row} ); } \`\`\` ## Code Splitting Split your code to load only what's needed: \`\`\`jsx import React, { Suspense, lazy } from 'react'; const HeavyComponent = lazy(() => import('./HeavyComponent')); function App() { return ( Loading...}> ); } \`\`\` ## Avoid Inline Functions in Renders Inline functions cause unnecessary re-renders: \`\`\`jsx // Bad return ; // Good const handleButtonClick = useCallback(() => { handleClick(id); }, [id, handleClick]); return ; \`\`\` ## Conclusion By implementing these optimization techniques, you can significantly improve the performance of your React applications.`, }, { filename: "docker-for-developers.md", content: `--- title: "Docker for Frontend Developers" date: "2023-09-01" excerpt: "A practical guide to using Docker in frontend development workflows" --- # Docker for Frontend Developers Docker can streamline your frontend development workflow and ensure consistency across environments. ## Why Use Docker for Frontend? - **Consistency**: Same environment for all developers - **Isolation**: Dependencies don't conflict with your system - **CI/CD Integration**: Easier testing and deployment - **Microservices**: Better for modern architecture ## Basic Dockerfile for a React App \`\`\`dockerfile # Build stage FROM node:16-alpine as build WORKDIR /app COPY package*.json ./ RUN npm install COPY . . RUN npm run build # Production stage FROM nginx:alpine COPY --from=build /app/build /usr/share/nginx/html EXPOSE 80 CMD ["nginx", "-g", "daemon off;"] \`\`\` ## Docker Compose for Development \`\`\`yaml version: '3' services: frontend: build: context: . dockerfile: Dockerfile.dev volumes: - ./src:/app/src ports: - "3000:3000" environment: - NODE_ENV=development \`\`\` ## Tips for Frontend Docker Setups 1. Use multi-stage builds to keep images small 2. Mount volumes for hot reloading in development 3. Consider using Docker for your API during development 4. Use environment variables for configuration ## Conclusion Docker can significantly improve your frontend development workflow, especially for complex applications or teams with multiple developers.`, }, ] samplePosts.forEach((post) => { fs.writeFileSync(path.join(postsDirectory, post.filename), post.content) }) }