All work
My Personal Website project cover

My Personal Website

A journey across three versions, from a template portfolio to an AI assisted UX engineering practice.

Web DevelopmentPortfolio

1. Why I built my own portfolio

I moved from frontend development into UX/UI design at the end of 2020. By the end of 2022, I had two years of UX/UI design experience and enough projects to start thinking seriously about building my own portfolio. I could have used Behance, but my own website felt more independent. It was also more fun because I could code again.

Behance was restricted in Vietnam at that time, so I did not want to depend on one platform. I wanted my own place to show my work. I could control it, change it, break it, fix it, and learn from it.

This became a longer journey than I expected. I moved from a Vue template, to an AI assisted rebuild, and then to my current workflow with AI coding agents.

2. Version 1 · Back to code

The first version launched in December 2022. I used an open source Vue and Tailwind portfolio template. I did not build everything from zero. Instead, I learned how to read, change, and maintain an existing component structure. This helped me return to code after two years of focusing on design.

I replaced the sample content with my own project gallery and structured project data. Step by step, I changed the routing, responsive layouts, theme, contact form, 404 page, and GitHub Pages deployment. The history shows 53 commits for features, fixes, content, and maintenance until March 2025.

This version helped me practise the basics again. I learned how to understand an existing system, find browser and routing problems, optimise images, and support different screen sizes.

It stayed live until March 2025. Yes, I really kept that super plain version online for more than two years. I was lazy, LOL. Still, it remained useful and kept my work independent from a portfolio platform.

  • Frontend: Vue.js and JavaScript.
  • Structure: reusable components, Vue Router, project data, category filters, and a saved light or dark theme.
  • User experience: responsive project pages, an EmailJS contact form, a custom 404 page, and client-side routing with React Router for seamless SPA navigation without page reloads.
  • Performance: compressed images and many responsive fixes for an image focused portfolio.
  • Hosting: GitHub Pages, with fixes for environment settings and public paths.
  • Deployment: automated with GitHub Actions.
53
Portfolio commits

Features, content, deployment, and maintenance from December 2022 to March 2025.

27 months
Live and maintained

I continued to add projects, fix problems, and improve the responsive layout.

Version 1 · Vue.js
The first live portfolio: a deliberately simple template led by visual content. It got me coding again.
The first live portfolio: a deliberately simple template led by visual content. It got me coding again.

3. Version 2 · AI assisted coding

For version 2, I changed my process. First, I designed a more complete website in Figma. Then I tried to match it in code. I used Figma plugins to create some starting code. I also pasted code into Claude and ChatGPT for explanations and fixes. I often continued until "You have hit your usage limit". LOL.

The process was still manual. I pasted the code, read the answer, tried the suggestion, tested it, and repeated. Cursor made some parts more agentic. I could write a prompt inside the editor, then let Cursor inspect and edit my code. I still gave small tasks and checked every result.

This version taught me how to turn a complete Figma design into a working website. AI supported my coding, but I still controlled the implementation. The website also became easier to maintain. It used reusable Vue components, structured project data, responsive navigation, private project flows, and shared image loading.

The repository has 174 commits. It has 15 case study modules that load only when needed. I also built an image component with IntersectionObserver. It starts loading an image when the user gets close to it (Lazy loading). Performance became part of the system, not only a final fix.

Version 2 stayed live for one year and four months, until I wanted to practise with AI coding agents and started building version 3.

  • Frontend: Vue and JavaScript.
  • Styling: Tailwind CSS.
  • Platform services: Firebase.
  • Architecture: reusable project templates and 15 case study modules that load when needed.
  • Experience: project filters, private project access, image previews, touch swiping, and responsive layouts.
  • Performance: lazy loading with IntersectionObserver, compressed images, loading states, and error states.
  • Deployment: Cloudflare Pages with automated CI/CD.
174
Iteration commits

Design work, features, responsive fixes, performance improvements, and deployment fixes.

15
Case study modules

Each project module loads only when the visitor needs it.

Figma
A complete homepage direction designed before development.
A complete homepage direction designed before development.
Deployed build
The Vue implementation after iterating with Claude, ChatGPT, Figma plugins, and Cursor.
The Vue implementation after iterating with Claude, ChatGPT, Figma plugins, and Cursor.

4. Version 3 · Agentic workflow

Version 3 is the website you are reading now. I built it with AI coding agents, Next.js, and TypeScript. This project is part of my journey towards becoming a UX engineer.

I did not design every page and any component, style, and variable in Figma. I only created a working frame to show the visual direction. My new process was simple. I prompted the agent, checked the result in the browser, used my design experience to find problems, and prompted again with clearer feedback.

The agents helped me keep Tailwind styles consistent. They also helped create light effects from reference images, adapt animation examples from CodePen, and complete repeated coding tasks. My role was to set the direction, find problems, check the quality, and decide what to change.

Through this project, I learned how to use AI tokens more carefully. I avoid giving the agent a large and unclear request, asking it to change everything at once, or repeating a prompt without explaining what was wrong. These requests use more tokens because the agent must inspect too much context and may change the wrong things. I get better results when I give one clear task, share only the relevant files and screenshots, explain the problem and expected result, then test the change before asking for the next step.

Version 2 took around one month to build. Version 3 reached a similar stage in about one week. This was about 75% less build time.

  • Frontend: Next.js, React, TypeScript, and Framer Motion.
  • Styling: Tailwind CSS.
  • Deployment: an automated Cloudflare workflow.
1 weeks
Version 3

Time needed to reach a similar stage of version 2.

~75%
Less build time

More time for case studies, testing, and improvements.

Working frame
The lightweight Figma direction: enough to communicate intent, without designing every page, token, or state first.
The lightweight Figma direction: enough to communicate intent, without designing every page, token, or state first.
Current build
The live Next.js site, shaped through prompting, browser validation, and repeated refinement.
The live Next.js site, shaped through prompting, browser validation, and repeated refinement.

4.1. Creating the hero icon set with AI

I used generative AI to explore and create the glass icon set for the homepage hero section. I set the visual direction, selected the strongest results, and refined how the final icons work together in the animated experience.

AI-generated glass icon explorations created for the portfolio homepage hero section
AI-generated explorations for the glass icon system used throughout the homepage hero.

4.2. Improving protected access

Version 2 had a useful flow for private case studies. Private projects had a clear lock icon. The website remembered which project the visitor wanted to open. After entering the password, the visitor returned to that project. However, the password and secret key were stored in the browser. This looked protected, but it was not a secure solution.

In version 3, I kept the same user flow but improved the system behind it. The server now checks the password. The secret comes from the deployment environment, not the browser code. After successful access, the browser saves a secure login cookie that website scripts cannot read.

Version 2 · Problem

Password and secret key visible in browser code

The credentials were bundled into the client-side JavaScript. Anyone who opened DevTools could read them, making the protection cosmetic rather than real.

Version 3 · Improvement

Server-side check, environment secret, and a secure HttpOnly cookie

The password is verified on the server. The secret never reaches the browser. After a correct attempt, an HttpOnly cookie grants access — unreadable by any page script.

4.3. Adding cookieless analytics and a privacy policy

I use Cloudflare Web Analytics to track overall visits, page views, traffic sources, and website performance. It is cookieless and gives me aggregate insights rather than creating profiles of individual visitors.

I plan to use these patterns as one input for analysing the portfolio UX from a hiring manager's point of view. For example, I can look at whether visitors reach the most relevant work, which case studies they explore, and where the journey may lose attention. The data cannot tell me who a visitor is or why they made a decision, so I will treat it as a signal and combine it with direct feedback when possible.

Even though this analytics setup does not use analytics cookies, I added a plain-language Privacy Policy and linked it from the footer. It explains what the website measures, the strictly necessary cookie used for protected project access, data retention, third-party services, external links, and how to contact me with a privacy question.

In the future, I may add deeper analytics, such as Google Analytics, to understand journeys and interactions in more detail. If I do, I will update the privacy policy, show visitors a clear consent choice when they arrive, and only enable that optional tracking after they give permission.

4.4. Validate AI output: Fixing the heavy homepage load

Code from an AI agent still needs human testing. While testing the homepage, I saw repeated resource activity when the hero section (in this Homepage) changed roles. The animation looked smooth, but the browser kept creating the same background and cube images again.

I found the problem in the transition logic. Every two seconds, the website removed the active background and four to six cube images, then created them again. I changed the logic so each image stays on the page after its first use. The next animation only changes its opacity, position, and movement.

After one full loop, the page keeps five backgrounds and fourteen cube images ready to reuse. The next loops create zero replacement image elements.

4.5. Conclusion · Design in code, systemise when needed

As a UX engineer, I found that when I already have a clear concept and visual direction, moving into real code is a faster way to explore and test ideas than designing every screen, component, and design system rule in Figma before development begins. Working in the browser lets me evaluate interactions, responsiveness, and technical constraints at the same time, then refine the direction through working prototypes.

This approach works well for a personal project where I can hold the full context and make decisions quickly. For larger, long-term products with several designers, especially when team members change often, a shared design system and clear design guidelines are still worth building. They preserve decisions, support handovers, and keep the experience consistent as the team and product grow.

5. Process

  1. Version 1: understand an existing component system, practise coding basics, and solve browser problems manually

  2. Version 2: design the full website in Figma, build reusable patterns, use AI for support, and test every suggestion

  3. Version 3: set the visual direction, prompt an agent, check the browser result, find problems, and repeat. Keep control of the decisions. AI can code quickly, but I am responsible for usability, consistency, performance, and the final experience

Thank you

For taking the time to explore this project.

All projects