Skip to content

Gotta go fast!

Portfolio Refresh

release date
2025
Avg. Lighthouse Score
99.5

Welcome to my 2025 refreshed portfolio!

In this post I'll go over the goals and process that went into building this version of my site.

98
Performance
100
Accessibility
100
Best Practices
100
SEO

Goals

  1. Speed - It had to be fast and I wanted to get as close to a perfect Lighthouse score as possible.
  2. Modern - I wanted to utilize the latest tech, Nuxt, Tailwind, and GSAP for subtle animations & microinteractions.
  3. Learn Something New - Get out of my comfort zone and try new things.

Process

I knew from the very beginning I wanted to stick with Vue but I wanted to take it a step further and explore the Nuxt ecosystem which up to this point I hadn't really had a chance or reason to use.

Choosing Nuxt lead me to Nuxt UI which brought with it Tailwind. Another tech that I had minimal experience with but that I wanted to get better at.

I also knew I wanted to host on Vercel's Edge network as I felt that would get me closer to that perfect Lighthouse score.

Animations

Hello, my name is Cesar

The opening sticker animation was made using an SVG that I designed in Adobe Illustrator and then animated the writing in GSAP.

The entire writing animation is a mere 6 lines of code.

onMounted(() => {
    gsap.set("#sig-1", { drawSVG: '0%' });
    gsap.set("#sig-2", { drawSVG: '0%' });
    const tl = gsap.timeline({ defaults: { duration: .6, delay: .3, ease: 'power1.inOut' } });
    tl.to('#sticker', { y: 0, opacity: 1 });
    tl.to("#sig-1", { drawSVG: '-100%', delay: 0.4 });
    tl.to("#sig-2", { drawSVG: '100%', delay: -.01 });
});

The sticker's dropshadow was made using an SVG filter:

<svg ...>
  <defs>
      <filter id="shadow">
          <feDropShadow dx="0" dy="6" stdDeviation="7" flood-opacity="0.3" />
      </filter>
  </defs>
</svg>

and then applied onto the <svg/> using a regular style attribute:

<svg style="filter: url('#shadow'); ...

The v-gsap-nuxt module makes it even easier to animate DOM elements simply through specialized attributes. This is method I used on the work history page to animate the history entries in as the page scrolls.

<element v-gsap.whenVisible.once.stagger.from="{ opacity: 0, x: -10, stagger: 0.2 }" >

Technologies Utilized

Frontend
Nuxt
Vue 3
Nuxt UI
Tailwind
GSAP
TypeScript