BUILD LOG · 001
From One Page to a Bilingual Multipage System
An architecture decision to stop accumulating sections inside one portfolio and turn them into real, equivalent Spanish and English routes.
When adding another section stopped being the problem
The previous portfolio worked. It already had a Spanish presentation, an English version, and content for my profile, capabilities, projects, and contact. It also had its own styles, modular JavaScript, a visual theme, and useful interactions worth preserving.
I was not rescuing a broken project or starting from an empty page. The limit became visible when I tried to make the site grow. Adding one more section looked simple until a more important question appeared: should this remain part of the same page, or did it now need to become a real page of its own?
As more content accumulated, it became harder to distinguish what belonged in Profile, what should live in Projects, and what needed Services or Contact. A small change could affect a different part of the journey. The structure still worked, but it was no longer a comfortable way to review, expand, and maintain the site.
Language and routes stopped being details
The change was not only about distributing content into folders. It also forced a decision about how Spanish and English should work.
Previously, switching languages could depend on dynamic replacements. That seemed sufficient for a smaller version of the site, but practical problems appeared as it grew: reviewing each language independently was harder, linking one page to its counterpart was less direct, and it was not always clear which document a visitor was actually viewing.
I decided to keep two real sets of pages: Spanish as the primary language, with an equivalent counterpart under /en/. The selector stopped replacing content inside the DOM and started navigating to a specific document.
That improved editorial review and navigation. Later, it also made it possible to establish clear relationships between languages with hreflang, define a canonical URL for each page, and build independent URLs. Technical SEO was a useful consequence of having real routes; it was not the only reason for the migration.
What I wanted to preserve
The reorganization did not justify replacing the whole project. The boundaries were clear:
- Keep native HTML, CSS, and JavaScript.
- Keep shared resources inside
/assets/. - Continue using static hosting.
- Keep Spanish and English as public versions.
- Avoid local paths or behavior that only worked on one computer.
- Preserve the interactions that already added value while making them clearer and more accessible.
- Validate each change before moving to the next part of the portfolio.
The intention was to reorganize an existing foundation, not to prove that a new tool could solve everything.
The decision: one page per responsibility
The solution was to use a folder for each section and an index.html inside every public route.
This means /projects/ represents a specific projects page, while /services/ represents a specific services page. Navigation no longer points to a hidden section inside one long document; it connects pages with defined purposes.
Each page can have its own title, description, active navigation state, and relationship with its counterpart in the other language. CSS, JavaScript, images, and icons remain shared where appropriate.
The architecture did not turn the portfolio into a complex application. It made explicit what had previously been mixed together: what is content, what is a route, and what is a shared component.
From one concentrated entry point to independent routes
Before
index.html
└── concentrated contentAfter
/
├── index.html
├── profile/
├── capabilities/
├── projects/
│ └── portfolio/
├── services/
├── contact/
└── en/
├── index.html
├── profile/
├── capabilities/
├── projects/
├── services/
└── contact/The diagram summarizes the public structure. Every directory uses its own index.html; the English version keeps equivalent routes inside /en/.
Where implementation became concrete
The idea of “using routes” was simple. Resolving the details was not always as straightforward.
A page such as /profile/ and a deeper page such as /projects/portfolio/ are not the same distance from shared resources. A relative reference that works from Profile can break from the case study if its depth is not adjusted.
That affected CSS, JavaScript, the favicon, the icon sprite, images, internal links, and the language selector. Checking Home was not enough: each route had to be opened over HTTP to confirm that every document could find the resources and destinations it needed.
Navigation also had to behave consistently across all documents. Each page needed to mark its current section with aria-current="page", keep a language selector pointing to its real counterpart, and provide accessible names for its controls.
On mobile, the menu needed a real button, an aria-expanded state, Escape-key closing, and focus returned to the control that opened it. When the viewport changed, it also had to correct its state rather than remain open where it no longer belonged.
Progressive enhancement completed that part of the work. With JavaScript, the menu can open as a mobile panel and the theme can persist. Without JavaScript, primary navigation and the language selector remain available. The theme control is hidden because it would have no real action; showing a control that only appeared to work would have been worse than keeping the initial theme.
What I decided not to do
Other options were available. I could have moved to React, added a router, introduced a static-site generator, or created a build system. None of those tools was wrong, but the problem at this stage did not require that level of complexity.
The portfolio was already static. It needed only a small set of routes, the content could remain real HTML, and the architecture did not require dynamic rendering. Adding another layer would have meant learning, configuring, and maintaining more pieces before confirming that they were actually necessary.
So I kept static HTML, shared CSS, modular JavaScript, and explicit routes. It was a decision about proportion: use the least complexity that solved the problem without closing off future growth.
Validating the complete system
The migration was not complete when the folders existed. I still had to verify that every route loaded over HTTP, that local assets did not return errors, and that internal links reached the expected document.
I also reviewed the Spanish and English pairs, active navigation state, the mobile menu, keyboard use, visible focus, and the transition from a mobile viewport to desktop. Screen sizes mattered because text, controls, and navigation could change composition as the available width changed.
The main content remained directly available in HTML. That makes the pages readable even if a module fails to initialize and prevents the architecture from depending on JavaScript to expose basic information.
Once those foundations were stable, it became possible to add a canonical URL for each page, hreflang, a sitemap, robots directives, and social metadata with a clear relationship between every URL and document.
What the new architecture actually gained
The new structure separated the portfolio more clearly. Profile could explain my path; Capabilities could organize evidence; Projects could present work by context; Services could explain the kinds of needs I could address; and Contact could reduce friction for starting a conversation.
It also created room to grow without turning Home back into a container for the whole site. A case study, a new page, or a technical note could be added as an independent route without changing the purpose of pages that were already published.
This does not remove the need to review links, translations, responsive behavior, or accessibility. It gives those issues a clearer place to be found and corrected.
What I learned
The main lesson was not that every portfolio needs many pages. It was that architecture begins by separating what should no longer remain mixed together.
A better architecture does not necessarily have more pieces. In this case, real HTML documents, explicit routes, and small components were enough for a static bilingual portfolio.
Complexity should be proportional to the problem.