Building Nikolas Dev Journey: How I Created My Developer Blog

Creating this blog wasn't just a coding project — it was a meaningful step in documenting my transition from philosophical studies to the world of software development. I built Nikolas Dev Journey to serve as both a personal journal and a professional platform, showcasing what I learn as I grow as a self-taught developer. In this first post, I'll walk you through how I structured, styled, and deployed this blog using modern technologies.

Technologies I Used

  • Next.js — React-based framework with powerful routing and SSR.
  • React — Component-based JS library for building UIs.
  • Node.js — Backend JS runtime used via Next.js.
  • Vercel — CI/CD and deployment.
  • Git & GitHub — Version control & collaboration.

Folder Structure

Blog Project Structurebash
1/app
2  /about
3    page.js
4  /blog
5    page.js
6    /posts
7      /how-i-built-this-blog
8        page.js
9  /contact
10    page.js
11  /components
12    Navbar.js
13    Footer.js
14    CodeBlock.js
15globals.css
16layout.js
17page.js

Styling & Design

I kept the design clean, minimal, and readable — optimized for both desktop and mobile:

  • A hero section on the homepage introduces the blog and links to the latest post.
  • Each page follows a similar layout with Navbar, content, and Footer.
  • Fonts are loaded via next/font, using Inter.
  • Backgrounds, spacing, and alignment are all responsive and visually balanced.

CSS Styling Example

Here's some of the key CSS that makes the blog look great:

Blog Stylingcss
1:root {
2  --background: #1a202c;
3  --foreground: #e2e8f0;
4  --accent: #63b3ed;
5  --font-mono: 'Fira Code', monospace;
6}
7
8.hero-section {
9  padding: 2rem 0;
10  display: flex;
11  flex-direction: column;
12  align-items: center;
13  justify-content: center;
14  text-align: center;
15  min-height: 90vh;
16}
17
18.hero-title {
19  font-size: clamp(2.5rem, 8vw, 4rem);
20  margin-bottom: 2.5rem;
21  font-weight: 900;
22  animation: fadeIn 1s ease-in-out;
23  line-height: 1.2;
24}
25
26.hero-button {
27  padding: 0.8rem 1.5rem;
28  background-color: var(--accent);
29  color: #ffffff;
30  border: none;
31  border-radius: 10px;
32  cursor: pointer;
33  transition: all 0.3s ease;
34}
35
36.hero-button:hover {
37  background-color: #90cdf4;
38  transform: scale(1.05);
39}

Deployment to Vercel

Deploying with Vercel took just a few minutes:

  1. Connected my GitHub repo to Vercel.
  2. Each commit triggers a build & deployment.
  3. Custom domain set up: nikolasdevjourney.com

Connecting Frontend and Backend

After successfully deploying the blog to Vercel, I integrated a simple backend using Next.js API routes. Instead of hardcoding posts directly into the frontend, I created a /app/api/blog/route.js file that returns blog post data in JSON format.

API Route Example

Here's how I structured my blog API route:

Blog API Routejavascript
1export async function GET() {
2  try {
3    const posts = [
4      {
5        title: "How I Built This Blog",
6        slug: "how-i-built-this-blog",
7        date: "2025-04-30",
8        excerpt: "Step-by-step guide of how I created my blog.",
9        category: "Blog Development",
10        tags: ["Next.js", "React", "Vercel"],
11        isFeatured: false
12      },
13      // More posts...
14    ];
15
16    return new Response(JSON.stringify(posts), {
17      status: 200,
18      headers: {
19        "Content-Type": "application/json",
20        "Cache-Control": "no-store"
21      }
22    });
23  } catch (error) {
24    return new Response(
25      JSON.stringify({ error: "Internal Server Error" }), 
26      { status: 500 }
27    );
28  }
29}

Frontend Data Fetching

And here's how I fetch the data on the frontend:

Blog List Componentjavascript
1'use client';
2import { useState, useEffect } from 'react';
3
4export default function BlogPage() {
5  const [posts, setPosts] = useState([]);
6  const [loading, setLoading] = useState(true);
7
8  useEffect(() => {
9    async function fetchPosts() {
10      try {
11        const res = await fetch('/api/blog', {
12          cache: 'no-store',
13        });
14        
15        if (!res.ok) {
16          throw new Error('Failed to fetch posts');
17        }
18        
19        const data = await res.json();
20        setPosts(data);
21      } catch (err) {
22        console.error('Error fetching posts:', err);
23      } finally {
24        setLoading(false);
25      }
26    }
27    
28    fetchPosts();
29  }, []);
30
31  return (
32    <div>
33      {loading ? (
34        <p>Loading posts...</p>
35      ) : (
36        posts.map(post => (
37          <div key={post.slug}>
38            <h3>{post.title}</h3>
39            <p>{post.excerpt}</p>
40          </div>
41        ))
42      )}
43    </div>
44  );
45}

This approach keeps the code organized, flexible, and easy to scale when I start adding more posts in the future. Since everything is still within the same Next.js app, deployment to Vercel remains seamless.

Lessons Learned

  • Be careful with case sensitivity in file names (Vercel is Linux-based).
  • Reusable components like Navbar/Footer save a lot of time and keep code consistent.
  • Planning routes and layout early made the site easier to scale.
  • Starting simple and iterating is more productive than chasing perfection.

What's Next?

This is just the beginning of the journey. I'll be writing about:

  • What I'm learning in Python & JavaScript
  • Web development tips and tutorials
  • Project breakdowns and reflections
"From metaphysics to machine code — it's been a surprising journey, but I'm just getting started."

💬 Comments & Discussion

Share your thoughts, ask questions, or discuss this post. Comments are powered by GitHub Discussions.