Skip to content
vp.Ven Petrov
WorkWritingAboutAt a glance
← Projects & notes
3D Spaces website migrationProject story · 3 min read

Moving 3D Spaces to Next.js while its email stayed on the old server

I rebuilt the virtual-tour website with AI coding collaborators, preserving its content and URLs. The cutover also had to protect the mailbox, enquiry flow and existing analytics history.

Ven PetrovLive websiteOpen project

3D Spaces presents virtual tours and related services for showing physical spaces online. I rebuilt its WordPress website in Next.js with AI coding collaborators, using the existing content, page organization and presentation as the reference.

The migration had a constraint beyond the website: incoming email still depended on the old hosting server. Moving web traffic could not mean retiring that server or replacing unrelated DNS records.

I had to treat the pages, enquiries, analytics and mailbox as different parts of the cutover, even though a visitor encounters them through one domain.

The restored 3D Spaces homepage with its original navigation, purple-to-orange accents and a dollhouse-style view of a property
A saved visual review of the rebuilt homepage. This is the corrected Next.js presentation, using the original site’s content and imagery.

Preserve the site people could already reach

The inventory included service pages, articles, archives, images, embeds, redirects and feeds. It became the checklist for the replacement. Matching the homepage would not establish that an old article URL, an archive or an image still worked.

The first migration pass preserved the content but lost presentation details. A correction pass restored header dimensions, typography, spacing and pricing layouts from the original pages, cached HTML and a read-only backup. Those details became bounded presentation fields rather than requiring the WordPress builder markup and plugin code to run in the replacement.

The Next.js implementation generates captured content pages and feeds statically, while search and enquiry handling run on the server. The live domain can be indexed by search engines; preview environments keep indexing disabled.

The launch checks covered 78 routes and 45 redirects. The sitemap has 38 selected canonical URLs, which is a different inventory from every preserved route. The detailed counts belong to migration verification, rather than being a measure of traffic gained.

A gallery card should open one tour

The tour gallery has 24 cards. It begins with poster images, not 24 embedded players running at once. A visitor opening a card creates that tour's iframe, the embedded viewer. Closing it removes the viewer, returns focus and restores page scrolling.

Optional-media consent alone does not load every player. Consent and opening a particular tour are separate actions. Browser checks followed both, including Escape to close the modal.

That behavior gives the gallery a clear interaction: browse the cards, choose a space, inspect its tour, then return to the list. I have not measured a before/after speed gain from the change.

The website moves; the mailbox stays

  1. 01Capture routesPreserve content, paths and redirects
  2. 02Rebuild viewsLoad one tour iframe after opening it
  3. 03Check deliverySubmit an enquiry and inspect the result
  4. 04Switch web DNSKeep unrelated mail records intact
The migration changed the website records while retaining the mail dependency on the old server.

Keep useful analytics without sending the enquiry

The existing GA4 property stayed in place, preserving its reporting history. The enquiry event sends a fixed form name rather than the person's name, email, phone, location or message.

Search tracking uses the generic search-page path and title without the search term. Rejecting optional cookies removes the Google tracking scripts.

The live Tag Assistant checks confirmed one initial pageview, one pageview after navigating inside the site and one enquiry event for the accepted test. That also checked a common migration problem: counting one navigation twice through overlapping tracking settings.

Change the web records, keep the mailbox

Only the two website DNS records changed. The 16 unrelated records, including mail and verification records, stayed intact. The old server remained available for its mailbox dependency and rollback.

Then the enquiry flow was checked on the live domain. The owner notification was accepted by its mail server, and the matching visitor confirmation was opened in Gmail Inbox with the expected summary and Reply-To.

Those are different levels of delivery evidence. The visitor message was seen in the inbox; the owner's final mailbox folder and an actual reply were not inspected.

The replacement went live on the same domain with HTTPS and its www redirect working. The launch application passed 65 tests and Linux checks. The website is now served from Vercel, while moving the mailbox remains a separate piece of work. Keeping those responsibilities separate was part of getting this particular migration over the line.

Project sources & checks
Live website ↗

Next.js replacement on the existing 3D Spaces domain.

Migration checks

The launch record covers 78 routes, 105 original assets, 45 legacy redirects, 38 canonical sitemap URLs and eight feeds. The launch application passed 65 tests and Linux checks.

Browser checks

The 24-card gallery starts with no players; opening a card creates one viewer. Tag Assistant verified initial navigation and enquiry events.

Email verification

The owner notification was accepted by its mail server. The visitor confirmation was opened in Gmail Inbox. Owner mailbox placement and an actual reply were not inspected.

On this page
Preserve the site people could already reachA gallery card should open one tourKeep useful analytics without sending the enquiryChange the web records, keep the mailboxSources & checks
Next.jsWordPressSEOVercelAnalytics

Connected to this

All writing
Sociedades Inactivas enquiries · Technical note

Saving an enquiry before trying to send its email

Astro local-services website · Project story

A local-services site assembled from city, service and FAQ records

Ven PetrovSoftware engineer · Barcelona
GitHub ↗LinkedIn ↗Email ↗

Find a project or a note

17 results

Transfutur ERP · ExperienceERP for transport and logisticsAs the sole engineer, I built an ERP from zero for transport and logistics. It supported roughly €5–6 million in annual invoicing across two offices, and I kept it running for about a year.Financial review lab · Project storyExploring a financial report with Python and FastAPII started with one income change, then opened up the same 54-page report: products, regions, cash flow, core adjustments and a dataset whose figures lead back to the source.Crude-oil narrative tracker · Project storyCrude-oil research from global news and market dataI wanted help following global events that could matter for crude oil. The prototype combines news research with calculated market and position values, while keeping recent assessments separate from the longer numeric history.MNQ time-series research · ExperimentTime-series prediction experimentsAn exploration of high-resolution market data: choosing what to acquire, checking its limits, comparing time intervals and testing whether a prediction survived later data and the cost of acting on it.NQ/MNQ backtest engine · Technical noteA missing closing bar left the simulator’s short position openThe strategy reset for a new day while a shared counter still counted yesterday’s short. A small replay shows why closing the position has to happen before clearing its state.Small-cap edge research · Project storyTurning small-cap trading ideas into repeatable researchI asked Claude Code for a fresh research system that could test named price patterns, compare later periods and carry its methodology into new sessions. One candidate shows how features, entry timing and costs fit together.Gadgeon Europe applications · ExperienceConnected-device dashboards and mobile apps at Gadgeon EuropeI worked on Ionic and Angular applications that brought several APIs into dashboards for energy monitoring and connected-device control, with releases and maintenance across multiple client versions.ctxforge · Project storyctxforge: discovering what to build before codingA context discovery framework that asks an LLM to act like a senior engineering interviewer: understand the idea, uncover requirements and agree the scope before an agent starts building.Sociedades Inactivas enquiries · Technical noteSaving an enquiry before trying to send its emailOn the Sociedades Inactivas catalogue, a visitor can ask about a company or send a general enquiry. The form separates saving that request from delivering its notification, including when the visitor retries.Astro local-services website · Project storyA local-services site assembled from city, service and FAQ recordsThe Astro site describes flooring and other local services across different cities. Shared templates check availability, read the matching content and select one FAQ set for both visitors and structured data.3D Spaces website migration · Project storyMoving 3D Spaces to Next.js while its email stayed on the old serverI rebuilt the virtual-tour website with AI coding collaborators, preserving its content and URLs. The cutover also had to protect the mailbox, enquiry flow and existing analytics history.Capture CRM · Project storyConnecting classified listings to contacts in a small CRMA Chrome extension and Next.js dashboard bring classified listings, platform profiles and contact history together. Saving a listing again can add the person who was missing from an earlier import.Product-description comparison bench · ExperimentComparing one model call with separate vision and writing stepsA small product-description tool lets me inspect the visual analysis before the copy is written, change the model used for each step and compare request measurements.Between Us · Project storyBetween Us: why I kept the first take and widened the shotI compared dialogue takes, asked for wider shots and more physical acting, then changed the workflow when its studio limited the scenes I wanted to make.Restaurant-service voice agent · ExperimentDesigning a restaurant-service call around the real offerI worked through a Spanish outbound agent prompt, corrected a free visit to the actual paid service and compared how two drafts handled transfers and bookings.Vapi and Telnyx voice integration · Technical noteThe Vapi agent could speak, but it could not hear me clearlyMy Telnyx number connected to the assistant, but the caller audio was distorted. Three codec tests recovered the connection without fixing that original problem.Warloop: Echoes of Solmara · Project storyWarloop: turning generated character art into a playable prototypeGood-looking character images became tiny figures, a backwards walk and misplaced bosses in the game. I worked through the gap between generated art and playable behavior.
esc to close · Tab to move through results