Website2026-08-21

Zlaja 2015 — a plumbing and electrical service website built around direct calls

A site from which you don't buy, but call. A visitor usually stands in a bathroom with water on the floor and asks for a phone number, not a catalog. Everything on this site is subordinate to that one second in which he decides whether to call or return to Google.

Zlaja 2015 site homepage with the title Plumber and Electrician Belgrade 24/7
Homepage - phone number and emergency services right at the top
Client
Zlaja 2015
Business
Plumber and electrician, emergency 0-24
Area
Belgrade and surroundings
Type
Multi-page site with work order panel
Technologies
PHP 8.3 · nginx FastCGI cache · MySQL · PWA
Site
vodoinstalaterzlaja2015.rs
Status
Live site, under active maintenance
Technology
PHP 8.3 · nginx + FastCGI keš · MySQL · PWA panel · Vanilla CSS/JS
01

Problem and context

What does Zlaja 2015 do

Zlaja 2015 is a plumbing and electrical shop from Palilula that works all over Belgrade and environment. Two professions, one phone number, and availability that the company states on the website as 0-24, seven days a week, with over thirty years of experience.

The plumbing part of the job is what keeps people calling at night: mechanical unclogging of sewers with a Rothenberg cable, high-pressure cleaning with the WOMA system, septic tank emptying, boiler installation and service, sanitary installation and leak detection. The electrical part covers complete installations, replacement of sockets, switches, fuses and switchboards, installation of lighting and fault detection — all of this is described on a separate page with electrical services.

The combination is more practical than it looks. When a pipe bursts in the wall and wets the installation, one man comes instead of two, and they don't shift the responsibility to each other. This is a real advantage of the shop and the site was written from the beginning so that this advantage can be seen, and not hidden behind the generic title "services".

View of services in Belgrade on the site Zlaja 2015
Services in Belgrade - choking, emergency interventions, sanitation, electrical installations
02

What needed to be solved

This is not a store. There is no looking around, comparing and returning the next day. A visitor has a leaking problem, usually at the worst time, and is looking for one thing — a number that works now. All that stands between him and that number is a loss of business.

From that one sentence, all requests fell out:

  • Phone number visible on every screen, without scrolling, as a touchable link that immediately opens the phone dialer — rather than plain text.
  • A site that opens on a poor mobile connection, because it is not opened at a desk but in the bathroom, in the basement, on the stairs.
  • Separate address for each service, because in the search you don't type "plumber" but "unblocking the sewage system Belgrade" or "boiler replacement price".
  • Proof that the equipment exists — A WOMA machine, a septic tank truck and a thermal camera are not something that every craftsman has, so it should be shown with a picture, not a claim.
  • A place to record jobs that isn't a notebook in the van.

The last item is what set this project apart from a regular service site. The site brings calls, but unrecorded calls can become unbilled jobs, so the site was accompanied by a work-order application.

Electrical repairs, fault detection and reasons for choosing a plumber
Electrical repairs and fault detection, reasons for choosing a plumber
03

Site structure — services, municipalities, emergency

The sitemap contains 20 URLs and they are not random. The homepage, seven service pages, one page about covered municipalities, gallery, contact, page for emergency interventions and legal texts.

The service pages are divided according to what people are really looking for: overview of plumbing services, then separate drain and sewer unblocking, WOMA high-pressure cleaning, boiler installation and service, septic tank emptying and electrical services. Each has the same skeleton — what the service is, how the work is carried out, FAQ, invitation at the end — but not the same text. The WOMA page compares high pressure to cable cleaning and explains when which is better. The boiler page lists the types and most common faults. The page on septic tanks talks about when emptying should not be delayed.

Municipalities have been resolved contrary to what is usually done. Instead of seven almost identical pages with the name of the municipality replaced — which is the fastest way for Google to rate that entire part of the site as thin content — there is one real page about the covered municipalities, and addresses like /vodoinstaler-zemun and /vodoinstaler-palilula lead to it and point to it with the canonical tag. The result is that local addresses can be shared and used in advertising, and search signals are not diluted on seven empty copies. All covered municipalities, together with settlements such as Kotež, Borča, Krnjača and Mirijevo, are listed on the page about locations around Belgrade.

Zlaja 2015 website on the phone
The same site on the phone, with the number under your finger
04

Call as the only right action

On there's exactly one thing a site visitor needs to do, and it's not hidden. Hero has two buttons — the phone number and the inquiry form — and the number is the first and larger. Below is a strip of three promises the shop makes: a guarantee, a thirty-minute delivery, and a free estimate. These are the company's claims and that's how they are written, in the first person.

Across the entire page is a floating call button that stays on the screen while scrolling. At the bottom of each page, without exception, there is the same strip with the question whether urgent intervention is needed and the number immediately below. A man who has reached the bottom of the page about septic tanks does not have to go back to the top.

The contact form exists as another option, for those who do not call immediately but ask for an estimate. It does not go through the PHP function mail() — messages are sent through an authenticated SMTP account with a DKIM signature, so inquiries arrive in the inbox rather than spam. A detail that once took too much time: in the text of the message, the word "BELGRADE" had the Cyrillic letter O instead of the Latin one, three times. It looks identical, but it's not the same letter, and such a small thing can push the message to the filter.

05

Gallery of works and equipment

For a craftsman, a gallery is a more serious item than for most activities. When someone is choosing who to let into the apartment at two in the morning, the picture of the work done is worth more than any description. That's why gallery of works is not an ornament but an argument.

It is divided into two parts — performed works and equipment. In the first, there are pictures from the field: patching pipes, mounting a toilet bowl, repairing leaks. In the second is what is not rented by the day — a Rothenberg machine, a septic tank emptying truck, a thermal leak detection camera and shop vehicles. Each image exists in two versions, WebP for modern browsers and JPEG as backup, with separately prepared thumbnails for the web.

An easily overlooked find also fell out of the gallery. Lightbox initially had an empty <img src=""> element that was filled only on click. An empty image source is interpreted by the browser as a request for the current page, so the entire page is loaded a second time only to be rejected. It has been replaced with a one-pixel transparent placeholder and the unnecessary request is gone.

06

Serbian and English without another copy of the site

The site has a language switch in the header. Common solutions for this are two sets of files, a translation table, or a ready-made plugin — all three mean that each text change is made in two places, and in practice the second place is forgotten.

Here it is done differently. In HTML, the text is written as a pair, the Serbian and English versions separated by one character, on the data-translate element. Before sending the page, the PHP output buffer goes through the document and leaves only the half of the pair that corresponds to the selected language cookie. The translation is located exactly where the text it translates is, so it cannot be separated from it.

The trap was in the cache. The site is behind the nginx FastCGI cache, which means that the finished page is remembered and served without running PHP — and that's exactly the step that chooses the language. Without the correction, the first visitor would set the language for everyone else for the next ten minutes. It was solved by the fact that the cache key includes a language cookie, so the Serbian and English versions of the same address have separate entries. It is a type of error that does not exist in testing, because the test is always made by one person with one language, and it appears immediately on the live site.

07

Technical performance

The site is written in PHP 8.3 behind nginx, without WordPress and without plugins that require ongoing updates. The pages sit in their own directories, the common parts — the header, footer, and end call bar — in a common inclusion, and the styles are divided into a critical part that goes embedded in the page and the rest that is loaded afterwards.

Foremost is the FastCGI cache with its own zone and a ten-minute time limit. The cache is intentionally skipped for form submissions, for URLs with query parameters, and for paths that process messages — because a cached response to a form submission means that another visitor sees someone else's confirmation.

Three things from the server configuration are worth highlighting, because they are repeated everywhere and cost a lot:

  • Redirecting from the www address was losing the path. The rule was returning the bare domain instead of the domain with the path, so every link to the www version of the subpage ended in the home page. One omitted argument in one line, and it means that every shared address and every backlink to the subpage does not go where it should.
  • The rule that prevents access to hidden files also blocked /.well-known/, and with it security.txt. The solution is an exception placed before the ban, not instead of it.
  • The site was in the wrong place for some of the visitors. The zone had an IPv6 record, and the vhost was only listening on IPv4. Visitors from IPv6-first networks — and that includes mobile operators in our country — were not guessing the right vhost. The correction is one line per block, but you can't get to it by viewing the site in a browser, because everything looks correct on most links.

Additionally, the header page carries a file system-level locked attribute as protection against unauthorized modification. The practical consequence is that every deploy must first remove the lock and then return it — which is deliberately awkward, because that's the point.

08

Performance and what really helped

Measurements were made before and after, in two passes, and the biggest gain did not come from where expected.

On the mobile device, the performance score went from 83 to 97 in the first pass and to 98 in the second. The time in which the main thread is blocked dropped from 610 milliseconds to 170, and then to 140. LCP on mobile dropped from 2.3 seconds to 2.1. Accessibility is 99, SEO 100, and best practices have been raised from 96 to 100.

The decisive move was not the compression of the images, but the moment of loading Google Tag Manager. Instead of starting immediately, it's delayed until the visitor's first interaction — a scroll, tap or click — or up to four seconds after the load, whichever comes first. Analytics still measures everything it needs to, but doesn't hijack the processor while the page is being drawn. More than two-thirds of the total gain came from that one move.

The best find was with fonts. The tick font subset was not preloaded, and the font was set to not wait if not ready. Consequence: on the first visit, with an empty cache, the letters ч, ш, ж, ч and д fell on the system font — in the title "Electrician" one letter was from another font, visibly larger and darker. On each subsequent visit, everything looked right, so the bug survived for months. It was solved by adding a preloaded subset to all twenty-two pages.

What is not resolved is worth saying just as clearly. Layout shift while loading on desktop remained at 0.194, above the recommended limit. Attempting to reserve height in advance made things worse at 0.265, so it was reverted. A real fix is ​​to redo the layout of the hero section, not add another property. On mobile, where this site's traffic is, that value is below 0.01.

09

SEO, Schema, and Local Visibility

Each page has its own title, description, and canonical URL, Open Graph and Twitter cards, and structured data that matches what's on it. The homepage and service pages carry the type Plumber with address, telephone, working hours from 00:00 to 23:59 all seven days and area of ​​work. The municipalities page lists twenty administrative areas as serviced areas. The questions that actually come to the client — how much does degassing cost, what is the warranty, what is the WOMA system — are written as FAQPage, so they can appear directly in the search results.

There were two passes through the W3C validator. The first showed four to six errors per page on all fifteen checked; after the second, they are all zero. The errors weren't cosmetic as much as they were contagious — one extra closing tag sat in the common inclusion of the closing strip, so it repeated itself on every page of the site. In addition: a style block that was placed directly in the footer instead of in the CSS file, a font preload tag with an incorrect value that the standard does not allow, and skipped heading levels where H2 was followed by H4.

On the infrastructure side, the DMARC policy was raised from watch to quarantine for all messages, CAA records were added to determine who can issue a certificate for a domain, and a security.txt was published with a contact to report the vulnerability. The sitemap is cleaned after passing through the Search Console — redirected URLs do not belong in the sitemap, because Google pulls them from there, sees the redirect and reports it as not indexed.

10

Work order panel

In addition to the site, a business-management application has been created on a separate subdomain. It is not public and not part of the site — it is not indexed by search engines, and sensitive directories are closed at the server level.

It is a one-page application that is installed on the phone as a native-like app and works even without a network, which is not a luxury in this business — half of the interventions are in the basement or boiler room without a signal. The content of the panel is the one that a technician actually needs:

  • Work orders with status — pending, in progress, completed, unpaid, canceled — and priority from low to urgent. Each work order includes field photos and a link to the client record.
  • Clients separately as individuals and companies, with multiple contacts and PIB for legal entities, and statistics per client: how many orders there were, how much was paid, how much is owed.
  • Costs by category — material, fuel, salaries, tools, vehicle, office — which are linked to a specific order, so you can see what each job really cost.
  • Reports: monthly with revenue, cost and difference, annual by month and performance overview by technician.
  • Roles: administrator sees everything, a worker sees only their own unfinished orders. Field staff do not need access to other workers’ payment records.

The status "unpaid" as an equal item next to "completed" is a small thing that tells for whom the application is written. The work that is finished and the work that is charged for are not the same, and for the craftsman that difference is the most expensive item of the year.

11

Outcome

What the client received

A site the client owns. No monthly platform subscriptions, no plugins that break at the next update, no expiring license. The code and database are on the server and can be copied.

Practically, it looks like this: a person types in a service and a part of the city in the search, opens a page that talks exactly about that service, and the number is under his finger before he can scroll anything. The call arrives at a number. The job is entered in the panel on the phone, with a picture and price, and at the end of the month there is a report instead of an assumption.

The site is under active maintenance. The last full pass covered nineteen pages in two screen and panel formats: no console errors, no horizontal overflow, no broken images, all sitemap URLs available, form checked until message delivery. What changes, changes on the live site, with a backup before each change.

FAQ

Frequently asked questions

Why does a craftsman even need a website when they call him through a referral?

A referral brings people who already know the name. The site brings people who don't know anyone and at two in the morning they type "choking off the Belgrade sewage system". These are two separate groups of customers and the other cannot be obtained without a website. In addition, the person who gets the number through a referral usually checks the site before calling.

Why does each service have its own page, and not all on one?

Because you don't type the name of the trade in the search, but a specific problem. Someone looking for a water heater replacement and someone looking for a septic tank drain are different people with different questions. The separate page can answer that question correctly, and the aggregate page can't answer either one properly.

Does the site open quickly on a weak mobile connection?

It was a requirement, not a wish, because a site like this opens in the basement and bathroom. The critical part of the styles is embedded in the page itself, the images are in modern formats with a reserve for older browsers, and the analytics are only started after the first interaction so as not to slow down the first display.

What is the panel and do I need it with the site?

The panel is a separate application for managing accounts, clients, expenses and reports, which is installed on the phone and works offline. It is not mandatory with the site. It makes sense when the number of jobs exceeds the limit at which the notebook begins to lie, and especially when more people work in the team.

Can the site be expanded later with new services or municipalities?

It can, and that is foreseen by the structure. A new service is a new page in the same form with its own title, description and structured data. New locations are added to the existing coverage-area page, without making empty copies that the search engine devalues ​​anyway.

How do you know something is actually fixed and not just reported?

By measuring before and after, on a live site. Performance scores, number of validator errors, time to first impression, and form behavior to message delivery — everything is double-checked. What didn't work is also recorded: scrolling content on the desktop is still over the limit and requires a layout overhaul, not another property in CSS.

Next step

Have a project that needs to work better?

Send me your goal and current situation. I will reply with a concrete scope proposal.

Start a project