Back to the blog

Why I rebuilt my portfolio with Astro

How I moved from a single Three.js page to 80 static Astro routes, the decisions behind the rebuild and the results I can prove.

Published
Reading time
7 minutes
Topics
Astro · Frontend · Portfolio

I rebuilt my portfolio because the previous website no longer represented the kind of work I wanted to show. It was a single page, relied heavily on visual effects, and every new project meant editing the HTML again.

The change was not simply replacing one technology with another. I moved from a closed presentation to a content system: independent pages, Spanish and English, projects and articles validated during the build, a generated sitemap, and JavaScript reserved for interactions that need it.

As of 10 October 2026, the build generates 80 static pages from 20 articles and 7 projects. That is the measurable result. The important part is how I got there and which problems Astro still does not solve for me.

The change, summarised with data

Area Previous portfolio Current portfolio
Public structure One URL with sections 80 static pages in the latest build
Projects Content embedded in the page 7 projects with dedicated Spanish and English routes
Blog No publishable blog section 20 articles and 3 topic hubs per language
Editing HTML blocks changed by hand MDX entries with validated metadata
Visual JavaScript Three.js particle background and several animations Focused scripts for the menu, theme, consent, analytics and progressive enhancements
Comparable organic data I kept no equivalent export 4,370 impressions and 24 clicks over 92 days in the available Search Console snapshot

The final row needs context. The measured period runs from 12 June to 11 September 2026 and covers the whole website. It does not prove that Astro caused those impressions, nor does it provide a direct comparison with the previous version. It confirms something more modest: independent pages are being discovered and shown for different queries.

Portfolio architecture: articles and projects in MDX collections pass through the Astro build and generate 80 bilingual static pages with metadata
The structural change: one validated content source generates independent Spanish and English routes.

What actually constrained the previous website

A single-page website is not invisible to Google by definition. My problem was more specific: projects, introduction and contact details shared the same URL, title and description.

That left little room to explain a project in context, link directly to it or let it answer a specific search. I had no clean publishing path for articles either. Every addition made the same document larger and more fragile to maintain.

The visual layer also had too much influence over the technical decision. The Three.js particle background attracted attention, but it did not help anyone understand my work. It had to load and execute code before adding useful information. Removing it was not an attempt to make the website anonymous; I decided its personality should come from the content, typography and interaction details.

The architecture I use now

The current structure separates content, routes and presentation:

src/
├── content/blog/*.mdx
├── content/projects/*.mdx
├── pages/blog/[...slug].astro
├── pages/proyectos/[...slug].astro
├── pages/en/blog/[...slug].astro
└── pages/en/projects/[...slug].astro

Articles and projects live in collections. Their schemas check fields such as title, summary, date, tags, role and stack before publication. Astro’s Content Collections do not write the content for me, but they stop an incomplete entry from silently reaching production.

Dynamic routes use getStaticPaths() to create one page per entry during the build. The browser receives pre-generated HTML rather than an application that needs to reconstruct every view on the client.

In how I organise Astro, MDX and bilingual content, I explain the less conventional part: each file contains Spanish and English blocks, and the build removes the language that does not belong to each route. It is not the only possible architecture. It avoids duplicating metadata in this project, but requires both texts to move forward together.

The decisions that changed the project most

One URL for each intent

Every project and article has a stable route, title, description, canonical, language alternates and structured data. The sitemap gathers those URLs, and there are now topic hubs for Web security, Astro and SEO, and Learning.

That does not guarantee a Google position. It lets each page explain one idea and receive contextual internal links. In this portfolio’s technical SEO, I detail which signals I generate and which ones I do not treat as a guarantee.

Content separated from layout

Adding a project used to mean copying HTML structure and checking the markup again. Now I add an MDX entry with known fields, and the templates handle the header, breadcrumbs, schema, navigation and English version.

The benefit is not typing fewer characters on one day. It is reducing the number of places I need to remember six months later. If I change the way an article date appears, I edit the template rather than twenty files.

JavaScript when it contributes something

Astro does not remove JavaScript by magic. The project still uses scripts for the mobile menu, theme control, consent, analytics and a few scrolling enhancements.

The difference is that the main content no longer needs JavaScript to appear. Even smooth scrolling loads after the first interaction and is skipped when someone prefers reduced motion. Navigation and reading continue to work as ordinary HTML.

What I can claim about performance

I can say that I removed Three.js and the particle background, reduced permanent animation and now generate the homepage as static HTML. I can also inspect which scripts the current build produces.

I cannot claim that the new website is a specific percentage faster because I did not preserve an equivalent measurement of the previous version: same device, network, hosting and test tool. A current Lighthouse score compared with a memory of the old website would not be a reliable before-and-after result.

That gap is one of the lessons from the project. If I started again, I would save these before migrating:

  • Lighthouse and WebPageTest captures on mobile and desktop.
  • Transferred weight by resource type.
  • Field LCP, CLS and INP if there were enough traffic.
  • Request count and JavaScript executed during the initial load.
  • The actual time required to publish a new project.

The current architecture makes those metrics easier to improve, but it does not replace measuring them.

The result I can verify

The clearest result is not a score: the website is no longer closed.

  • The current build generates 80 pages without maintaining 80 HTML documents by hand.
  • The 20 articles and 7 projects share schemas and templates.
  • Spanish and English have consistent routes, canonicals and alternates.
  • Articles can be grouped into topic routes and linked to each other.
  • A metadata error can stop the build before reaching production.

The first-party Search Console snapshot adds an external signal: between 12 June and 11 September 2026 it recorded 4,370 impressions, 24 clicks and an average position of 17.59. Those are small numbers, and the 0.55% CTR leaves clear room for improvement. I would rather report them that way than present them as an unqualified success.

They also show why the architecture matters. Impressions do not come only from the homepage: Spanish and English articles and project pages appear in the report. The structure creates that search surface; the content and its quality determine how far it goes.

What Astro did not solve for me

Astro was a good tool for this case, but it did not make the difficult decisions:

  • It did not decide which projects deserved a page.
  • It did not write useful titles or specific descriptions.
  • It did not automatically make the website accessible or secure.
  • It did not stop some pieces from starting without enough sources or evidence.
  • It did not create a simple editorial flow for someone who does not use Git.

That last point matters. MDX and Git fit my portfolio because I develop and publish it. For a client who edits every week, a CMS may be a better decision even if it adds infrastructure. The right technology depends on real maintenance, not on which option produces the cleanest HTML.

What I would do differently now

I would have measured the previous website before deleting it. I would also have defined the bilingual map, content structure and evidence I wanted to retain for each project from the start.

I would not change the main decision: separating content into pages and using a static build suits a portfolio that needs to explain work, publish articles and run with few server-side pieces.

The rebuild has achieved its goal when I can add an idea without redesigning the whole website. That is the change I value most: the portfolio is no longer a finished piece that ages, but a system I can keep feeding.

The same decisions about structure, performance and maintenance are part of my Astro web development service when a project is a good fit for this kind of architecture.