← Back to blog

Why we migrated a client from Vue 2 to Nuxt (and what broke along the way)

Daniel García·

This real estate client’s site had been running for years on Vue 2 with Vue CLI, and it worked fine — that’s the uncomfortable part of telling this story, because we didn’t migrate because something was broken, but because Vue 2 stopped receiving support, and staying there in the medium term meant piling up technical debt on purpose.

The first surprise, and a big one, was SEO. The old site was a pure SPA: everything rendered on the client, and for a real estate business that lives on Google indexing every property listing properly, that was already a problem before we touched anything. Moving to Nuxt with SSR wasn’t just “updating dependencies,” it meant rethinking how each property’s URLs are generated and what gets sent pre-rendered from the server.

What broke, to be honest: the repository system that talked to the Symfony API. It had been built for plain axios inside classic Vue components, and it had to be entirely adapted into composables. It wasn’t hard, but it was one of those tasks that seem mechanical until you run into an endpoint that returns a different format depending on whether there are images or not, and nobody remembers why it was built that way.

Property search on production also broke briefly, for about two hours, due to a difference in how Vue 2 and Nuxt handle reactive state in large listings. We caught it fast because we had a client looking at the site that same day. Not our finest moment, but it was fixed before it became too noticeable.

Was it worth it? Yes, but not for what these migrations are usually sold as. The site isn’t dramatically “faster” for the average user. What we gained is that there’s now a clear maintenance path for the next few years, instead of a closet full of dependencies that will one day stop installing.

If anyone asks me when to migrate a project that “works fine,” my answer is: when the cost of not doing it starts to outweigh the risk of doing it calmly, not the moment the next major version shows up.

vuenuxtmigration