Building My Personal Website

Building My Personal Website

After years of putting it off, I finally took the plunge into building my personal website. What started as a simple portfolio project evolved into something much more meaningful – a digital space that truly reflects who I am and what I create. I want to share the story of how this site came to be, including all the technical decisions that shaped it along the way.

The foundation of my website rests on Next.js with TypeScript. For styling, I went with Tailwind CSS – not just because it's trendy, but because it genuinely made my development process smoother and more intuitive.

Initially, I considered building a custom backend, but then I realized Ghost could provide exactly what I needed - from typography to media management, and even integration with external resources like Spotify. I wanted a content management system that wouldn't get in my way, yet powerful enough to handle everything from casual blog posts to detailed research articles. Ghost turned out to be perfect for this, and I host it on Pikados, which has been remarkably cost-effective. Everything runs under my custom subdomain (blog.moaadkhamlich.com), managed through Cloudflare. Unfortunately, this domain needs to remain accessible to avoid breaking newsletter subscription links.

The admin panel is my favorite aspect of this project. It allows me to manage my blogs directly through the Ghost Admin API, which generates specific URLs for each piece of content. I built this system with two goals in mind: first, to have a simple way to monitor and manage content that would encourage me to create more, and second, to ensure that even non-technical users could benefit from this type of service.


My CV is handled through the admin subpage as well. Instead of using a traditional static PDF or HTML page, I've implemented a dynamic CV management system using Vercel's KV (Key-Value) storage. This approach allows me to maintain a structured JSON representation of my professional information, which includes everything from personal details and work experience to skills and publications. The data is stored in Vercel's KV store and cached with Next.js's caching system for optimal performance. The system also handles file uploads for profile images and PDF versions of the CV, storing them securely in blob storage (I had two files to manage namely the CV itself in pdf and the profile image).

Content organization turned out to be surprisingly straightforward. Each page on my site, whether it's books or movies, simply relies on a filter applied to blog posts with the corresponding tag (e.g., tag:book). Through tags, I can expand content related to specific blog types, such as movie metadata (star rankings, year, and so on). It's amazing how much functionality you can achieve with simple tags!

The Ghost integration worked out better than I expected. The content API makes real-time updates seamless, and I get robust SEO optimization out of the box. One of my favorite features is the built-in newsletter functionality – it just works, no additional backend setup required. For staying in touch with readers, I integrated a contact form using Mailgun's free tier, along with newsletter subscription capabilities.

From a cost perspective, this setup has been surprisingly economical. I'm running on Pikados for Ghost hosting (just $2 per month, with $5 initial credits making the first two months free). Cloudflare handles domain management, which I also used to register the domain on Mailgun so emails would come from @mail.moaadkhamlich.com. Combined with Vercel's free tier for frontend hosting and Mailgun's free tier for email services, it's remarkable how far you can go with modern web services without breaking the bank.

The technical implementation, while robust, remains clean and maintainable. Here's a glimpse at how I fetch content using Ghost's Content API:

export async function getPosts() {
  const response = await fetch(
    `${process.env.NEXT_PUBLIC_GHOST_API_URL}/ghost/api/content/posts/?key=${process.env.NEXT_PUBLIC_GHOST_CONTENT_API_KEY}&include=tags,authors&formats=html&limit=all`
  );
  

Looking ahead, I'm considering packaging this setup as a template for others to use. It would be perfect for academic portfolios, personal blogs, review websites, or research showcases. The architecture is flexible enough to adapt to various needs while remaining simple to maintain.

For more information or to contribute to the project, don't hesitate to contact me. I'm excited to keep evolving this space and sharing more about the journey. Stay tuned for more updates as this platform continues to grow and adapt to new needs!