
Case study · Software development
A bilingual websitefed by the agency's own listings
Antibes · Côte d'Azur and Vosges
Listings, search, blog and enquiries in French and English: the Next.js website of an Antibes estate agency, fed by its own listings.

- Client
- Angeles Immobilier
- Sector
- Estate agency · sales, lettings and property management
- City
- Antibes
- Our role
- Design and development, from listings integration through to deployment
Seven chapters
01
One agency, two markets, two languages
Angeles Immobilier is an estate agency based in Antibes. It sells, buys and lets flats, houses, commercial premises and land on the Côte d'Azur, and offers a property management service to landlords. Since March 2025, a branch in Pouxeux has also covered the Vosges.
- Côte d'AzurAntibes · sales, lettings, property management
- VosgesPouxeux · branch opened in March 2025
Part of its clientele does not speak French: foreign buyers, owners living outside France, short-stay tenants. The website therefore had to exist in French and English, with the same listings in both.
Language-prefixed URLs
/fr/French, by default/en/English
Same listings, only the interface changes
next-intlnext-intl handles language routing and interface text, stored in one file set per language. Listings are shared by both versions: only the interface changes.
02
What the website had to solve
- Being foundAn estate agency lives on its listings, and a listing that cannot be found on a search engine does not make the phone ring. Each property needed an indexable page with its own title, description and sharing image, and a sitemap that follows the catalogue.
- Two markets, no duplicatesThe website also had to separate two very different markets, the Côte d'Azur and the Vosges, without duplicating data. Old listing addresses, already shared or indexed, had to keep leading to the right property.
- Reliable enquiriesFinally, every enquiry had to reach the agency reliably, with an acknowledgement for the visitor, without opening the door to spam or exposing the data entered.
03
Showing what the agency already publishes
The listings themselves are entered in the agency's transaction software, which exports them with their photos. The website was not meant to become a second data-entry tool: it had to display what the agency already publishes, with no duplicated work.
From the agency's software to the online listing
- Transaction softwareListings are entered there, then exported with their photos.
- Export fileOn a mounted volume: a new version appears without rebuilding the site.
- ParsingThe website reads the file and fixes encoding defects in descriptions.
- Département filter06 for the Côte d'Azur, 88 for the Vosges.
- CacheFive minutes for results, an hour for the town list.
Structured record
- Price
- Floor area
- Rooms
- Bedrooms
- Amenities
- Photos
Illustration: values hidden.
TypeScriptA listing has several dozen fields. Describing them in a single type prevents mismatches between the source file, the search and the display. Type checking runs before every commit, alongside ESLint and Prettier.
04
Search, then open the listing
A search engine by listing type, town, property type, number of rooms, price bracket and floor area. A detailed page per property, with photo gallery, full-screen viewer and suggestions of other properties.
Search criteria
A property page
- Photo galleryEvery photo in the listing.
- Full-screen viewerTo browse the photos at full size.
- Other propertiesSuggestions at the bottom of the page.
Dedicated pages
- Buy
- Rent
- Property management
- Vosges
- About
- Contact
- Blog
05
Pages search engines can find
Listing pages are rendered on the server. Each one generates its own metadata: a title with the property name and town, the property description, and an Open Graph image taken from its photos. The sitemap automatically lists every property for sale and to let, and pages declare their equivalents in the other language.
A listing page's metadata
- Title
- Property name and town
- Description
- Property description
- Sharing image
- Taken from its photos
Sitemap
- Every property for sale
- Every property to let
- Equivalent in the other language
Old addresses
Old listing addressMatching property page
Support for old listing addresses, which lead to the matching property page.
06
Every enquiry gets through
An enquiry form that sends two emails: a notification to the agency and a confirmation to the visitor. Sending goes through Resend, with email templates written in React.
Enquiry sent
- NotificationTo the agency, ready to reply directly.
- ConfirmationTo the visitor.
What the route checks
- Every field is validated
- No line breaks in the email address, to prevent header injection
- Message length is capped
- Submissions are limited per IP address
Logs never contain the values typed into the form.
07
One service, from branch to production
The Next.js router renders pages on the server and hosts the internal API routes in the same project: reading listings, listing towns, relaying the blog, sending emails. One service to deploy and monitor.
developImage published to the registryContainer restartedStagingmainImage published to the registryContainer restartedProductionReverse proxy · HTTPS certificates
- DockerThe image is built in several stages on Node.js Alpine, from Next.js standalone output, and runs as an unprivileged user. Environment variables are injected at build time from a secrets manager and are never committed.
- GitLab CIThe develop branch builds and deploys the staging environment, main the production one. Each deployment pulls the image published to the registry and restarts the container behind a reverse proxy that handles HTTPS certificates.
- SentrySentry is set up on the server, edge and browser sides. An unavailable listings source or an empty result is reported as a signal without breaking the page.
Today
What the website does today
- For visitorsA visitor can browse, in French or English, properties for sale and to let on the Côte d'Azur and in the Vosges. They filter by town, property type, number of rooms, budget and floor area, then open a page with every photo, the property's features and other suggested properties.
- For enquiriesFrom each property page, and from the contact page, they can send an enquiry: the agency receives it by email, ready to reply directly, and the visitor receives a confirmation.
- For landlordsLandlords have a page dedicated to property management. The agency's Google reviews appear on the home page and the Vosges page. The blog publishes articles in both languages.
- For the agencyFor the agency, the online catalogue follows the transaction software's export with no re-entry. Old listing links still work, and every new property is added to the sitemap automatically.
Tech stack
The project's technologies, and what each one does
- ReactNext.js website: listings, search and contact forms.
- TypeScriptTyping of the website and its API routes.
- Node.jsNext.js server and API routes in production.
- DockerProduction image of the website.
- GitLabContinuous integration and deployment.
A similar project?
Tell us about your situation. The first conversation is free and without obligation, on site in Nice and the surrounding area.





