DDD WIKI
The site of a Warsaw pest control company rebuilt from scratch after an outage in which one address out of thirty-three still worked. Fifty-three pages, a bespoke theme with not a single classic plugin, and a sitemap of our own โ all in five days.
Challenge
The site reached us in a state of outage: only the home page worked, and its content had picked up foreign insertions and outbound links the owner had never added โ hidden so that they were not visible in a browser. The whole thing had to be rebuilt without losing a single indexed URL.
Solution
Instead of cleaning the old installation we built a new one: a fresh WordPress, a bespoke theme with no page builder and no classic plugin at all, content generated from source files and imported idempotently. Fifty-three pages โ the three pillars of pest control, ozone treatment, nine pests, six property types and eighteen districts of Warsaw. Plus our own sitemap, a form that saves every enquiry in the database, and a full security layer verified by measurement rather than by declaration.

What we built โ element by element
A pest control site built from scratch
DDD WIKI deals with pests in flats, apartment blocks, offices, restaurants, hotels and warehouses across Warsaw. We built the company a new site: its own WordPress theme, fifty-three pages and a back end with not a single classic plugin. The next steps show the key parts.
- Rebuild
A new site instead of cleaning the old one
The diagnosis took half an hour: the 404 was coming from the web server rather than from WordPress, so the request never reached the CMS at all โ while the REST API returned all thirty-three pages with their full content. The routing had failed, not the database. A cleaned installation never gives certainty, though, so we went for a clean one: new WordPress, new theme, content moved with an integrity check on every file. The client logo โ the only file carried over from the old installation โ was checked byte by byte on its own.
- Content
Fifty-three pages from a single source
The content is not typed into an editor: it lives in source files that a generator assembles into pages, and an importer writes them into WordPress by slug, so every rerun updates instead of duplicating. Along the way we hit a trap no eyeball audit would catch: the WordPress sitemap returned valid XML with a 404 status, and the robots file pointed straight at it. So the theme got its own sitemap generator โ status 200 and modification dates taken from the real entries.
- Local SEO
Eighteen districts without a copy factory
The competitors on page one run over a hundred pages cloned with the district name swapped. We built one page per district covering all three pillars, with content that follows the buildings: a 1970s concrete block means cockroaches in the ventilation shafts, a tenement means bed bugs and mice, a new estate with an underground garage means rats and mosquitoes from the greenery. The rebuild changed the URL structure, so twenty-four old addresses were each accounted for: a redirect, native old-slug handling, or a deliberate 410 where we wanted Google to forget them faster.
- Enquiries
A form that does not lose the lead when email fails
An ordinary form sends an email and stops there โ if the mail does not go out, the enquiry vanishes without a trace. Ours saves it to the database first as its own entry, with the phone number, the service, the source page and the date in the list view, and only then tries to send the notification, recording the delivery status next to the enquiry. The owner can see from the list whether the mail went out at all, without opening the mailbox.
- Security
No plugins, and safeguards measured rather than declared
The plugin directory in production is empty โ everything plugins usually do is done by the theme. The security layer went in as a must-use module, and we checked it as an anonymous visitor, with no cookies: seven different routes to enumerate account names all return 404, the login message is identical for a wrong password and a non-existent account, and the password reset limit kicks in before anything reaches the database. Alongside it, a check that nothing broke: fifty-three pages, fifty-three 200s, zero PHP errors.