2025

|

UX/UI, Front End

Landing page for Onion App

Landing page design for Onion App made with Astro framework.

Building the Onion landing page in Astro

Onion is a project management tool I am building for Spanish speaking teams in Latin America. The product lives at app.getonion.app and runs on React, TypeScript and Supabase. However, the landing page at getonion.app does not.

This is a short write up of how I built it and what I learned about writing code alongside an AI assistant instead of handing the whole thing over.

Why Astro framework

The app already had a React setup, so reusing it would have been the path of least resistance. I did not want that. A landing page is mostly static content that needs to load fast and rank well, and shipping a client side router plus a hydration bundle to serve four sections of copy is the wrong trade.

I learned that Astro ships zero JavaScript by default. Everything renders to HTML at build time, and interactivity gets added only where I explicitly ask for it. This was my turning point, I saw the benefits and thought "Why not?". Also, I was eager to explore this new framework.

There was a second reason. I wanted to write HTML and CSS by hand again. Working inside a component library for long enough turns styling into an API you call rather than something you actually reason about. Astro let me drop back down to the layer where I could see what I was doing.

What the build actually involved

The site is bilingual, with locale prefixes on both languages (ES and EN). The root index.astro does a server side redirect to /es and falls back to an HTML meta refresh for anything that does not follow the redirect header. The rest:

  • A layout component holding the head tags, meta description and Open Graph fields
  • Section components for hero, features, and a closing CTA pointing at the app
  • CSS custom properties for color, spacing and typography, written directly rather than through a utility framework
  • A responsive grid built with CSS Grid and container queries instead of breakpoint soup
  • Deployment on Vercel, with DNS and the domain itself on Cloudflare

Writing the CSS by hand was the slowest part and the part I got the most out of. Grid areas, clamp based fluid type, and logical properties are all things I had used inside abstractions without fully understanding. Doing it from scratch on a small surface fixed that.

The problem of coding with Claude Code

I used Claude Code as a primary tool. The hardest part was to know what to delegate, and knowing how to iterate with it. The first version of the hero section was almost entirely generated. It worked, it looked fine, but the spacing, the placements and the copy felt odd. It was nothing like the live version. It was all AI generated content, and I knew that it could be a lot better.

First iteration

So, I tried to delegate to Claude code the stuff that did't work for me at first or second try when I made it by hand. In this way, I learned the technical stuff and also avoided getting stuck. In practice that split looked like this:

Delegated: Astro config, the redirect logic, sitemap and robots setup, Vercel deployment configuration, repetitive content refactors across files.

Written by hand: Layout decisions, core messages, the entire type scale, all the responsive behavior, and any CSS where I would have had to look up the property anyway, fixing AI hallucinations.

The other thing I learned is that reviewing generated code costs more than writing it when you do not already know the domain. If I cannot tell whether a solution is good, reading it does not teach me much. I just end up trusting it. When I know the domain, review is fast and delegation is a clear win. That asymmetry ended up being the actual decision rule.

What I would do differently

I would set the design tokens before writing a single component. I did it in the opposite order and spent an afternoon replacing hardcoded values that had spread across five files. It was fun though.

I would also write the English version at the same time as the Spanish one rather than after. Feeding a second locale into copy that was written monolingually meant rewriting sentences that had been structured around Spanish word order. And Claude sometimes (idk why) made changes to other things apart from the content.

Where it stands

The landing is live at getonion.app and feeds into the app at app.getonion.app. Next step is the blog structure, which will run on Astro content collections, and the first batch of Spanish language SEO articles. Also, legal pages and some showcases. Working with an AI assistant made me more deliberate about what I chose not to automate.

Other projects

Sign Generator

Design and development of an internal tool for Toteat salespeople and other teams.

See project ->

Toteat web and digital experience

UI/UX Web ecosystem redesign for Toteat an all in one software for restaurants.

See project ->

Ninja Hubs landing and ads

Conversion oriented landing and ads design for Ninja Hubs

See project ->