Website2026-08-21

Glass Service Bošnjace — site of an auto glass shop near Leskovac

Car glass does not break as agreed. A man calls on the same day, from the road, with the phone in his hand. The entire site is built around those three facts: that the number is within easy reach on every page, that the offer can be requested without a price list that would not be accurate anyway, and that the store can be found by whoever types the name of their city, not the name of the store.

The homepage of the Glass Service Bošnjace website with the title about auto glass replacement in Leskovac
Homepage — "Auto Glass Leskovac, professional replacement and repair"
Client
Glass Service Bošnjace
Activity
Auto glass - replacement, repair, ADAS calibration
Area
Bošnjace and Leskovac, Jablanica and Pčinja districts
Type
Multi-page site with offer form
Technologies
PHP 8.3 · Nginx · MariaDB PHPMailer
Site
glassbosnjace.rs
Status
Live site, under active maintenance
Technology
PHP 8.3 · Nginx · MariaDB · PHPMailer
01

Problem and context

What does Glass Service Bošnjace do

Glass Service Bošnjace is an automotive-glass workshop in Bošnjace, on the road between Leskovac and Lebane. It replaces windscreens, side and rear glass, repairs cracks and stone chips, restores headlights and calibrates ADAS cameras after glass replacement. The business was registered in 2011.

Two facts shaped the entire website. First, customers rarely have time to browse: a windscreen may crack that morning, or a vehicle may be left without a side window, so the phone number and quote request must be immediately available. Second, much of the work goes through insurance, which means the first conversation often concerns paperwork as much as glass: what the policy covers, who submits the claim and how payment is handled.

The workshop serves the Jablanica and Pčinja districts and travels toward Niš, Prokuplje, Pirot and Vranje. A customer in Vlasotince is unlikely to search for the workshop by name; they search for “auto glass Vlasotince.” A site with only one general service page would have little relevance for that local query.

The website also states that the workshop belongs to the European Automotive Glass Experts network and offers a lifetime installation warranty. These are the business’s stated service terms, presented as such rather than as results independently measured by me.

Service cards on the site Glass Service Bošnjace: windshield replacement, repair, insurance
Complete services - windshield replacement, repair and work through insurance
02

What needed to be solved

The request was not "make a website for the service", but five specific things:

  • One-click phone, from every page. Not in the footer, not after the scroll. In the header, as a button, both on the phone and on the computer.
  • Offer without price list. The price of the glass depends on the model, version of the glass, sensor, heater and camera behind the rearview mirror. A published price list would be either inaccurate or useless, so a way had to be found to gather enough data for the right price.
  • Insurance explained in the driver's language. What does the glass policy cover, what does the insurance cover, who fills out the paperwork and who charges whom.
  • Visibility by city, not by store name. The search goes to "auto glass Leskovac", "windshield replacement", "glazier Vranje".
  • All this on the phone, on a mobile connection. The visitor is literally on the side of the road. A site that takes five seconds to load is a site to close.

ADAS was a special case. Modern vehicles have a camera and sensors attached to the windshield, and after each glass replacement, these systems must be recalibrated. Drivers are increasingly asking for it as a separate service and typing it as a separate term — so it had to get a separate space on the website, and not a footnote under the glass replacement.

Shop results section on the Glass Service Bošnjace site
Section "Our results" - the numbers that the shop highlights for its work
03

How the website was put together

The main navigation has five items — Home, Services, Osiguranje, About us, Contact — plus a phone number and a prominent button for an online offer. Five items is the limit after which the phone menu becomes a list.

Services are intentionally one long side with anchors, not seven thin sides. Seven sections: introduction, what we do, what the process from call to warranty looks like, ADAS calibration, materials and adhesives, vehicle brands and questions. Each service has its own anchor, so the link from the footer or from the homepage leads directly to its own part of the page.

The reason is simple: there are not seven different texts for seven separate pages. There is one job described from seven angles. The seven thin pages would cannibalize each other in search and none would have enough content to mean anything.

What is got special sides are cities. Thirteen city pages — Niš, Vranje, Prokuplje, Pirot, Aleksinac, Bujanovac, Preševo, Surdulica, Vlasotince, Lebane, Bojnik, Medveđa, Grdelica — plus a special page for ADAS calibration and its Leskovac variant. There is also a difference in terms of content: distance, going to the field, how long it takes to get there.

The old URLs from the previous version of the site were not left to die. There is a special set of server-side redirects for them, so /windshield-glass, /glass-repair, /truck-glass and other old servants lead to the appropriate anchor on the service page instead of empty.

Glass Service Bošnjace website at phone
Same site on phone
04

Online offer - five steps instead of a price list

Instead of a price table, the site has a form for an online offer in five steps: client data, service selection, location, vehicle data, then review and sending.

The first step separates natural persons from companies, because the company asks for the invoice and data for the invoice, but the natural person does not. Another chooses a service — glass replacement, repair, repainting, ADAS calibration or headlight polymerization. The third asks where it is done: in the service center or at the client's address. The fourth asks for the make, model, year and chassis number, which is checked for seventeen characters, because it is the only information that unambiguously tells which glass goes into that vehicle. The fifth shows all the data entered before sending.

Why steps and not one long form: a form with twenty fields on the phone is not filled, but abandoned. Five screens with several fields each and a visible counter give the same information, and it reaches the end.

Photos of the damage can be sent along with the request, which in practice solves half of the conversation in advance — you can immediately see from the picture of the crack whether it is being repaired or replaced.

When the form arrives, the email leaves the store's domain, signed with the DKIM key of that domain, and lands in their regular inbox. It's not cosmetic: a message sent by a site, signed by a third party, regularly ends up in junk mail. Tested here with a full send, with all fields, and tracked to delivery status.

05

The page that existed and didn't

In one of the regular fleet checks it turned out that the Services page was an empty shell. Header, call to action and footer — and no page content between them. That page's sections folder was never in the repository and didn't even exist in the backup, so PHP include silently crashed.

The consequence was bigger than it sounds: nineteen addresses led there. Fourteen old redirection servants, ADAS redirection and all footer anchors. Everything was returning a neat 200 response and everything was blank.

This is the type of failure that a routine check doesn't see. A PHP include that doesn't find the file doesn't break the page — it just doesn't print it. The header works, the footer works, the certificate is in order, the answer is 200. From every automatic check, the site looks healthy. That's why the check "if the page returns 200" is not a check that there is content on that page.

The site was reconstructed from scratch, in seven sections, with content assembled from the existing text of the store — the cover card, the city pages and the insurance page — and supplemented. The anchors were returned, the cover cards were tied to them, and only then did the redirects make sense again.

06

The form that sent three emails

The same check revealed another problem: the contact form sent three emails per send, and the offer form sent two.

The cause was not in form but in where her script was loaded from. The same file was streamed from three places — as a goal tag within a section, from a version tag footer, and through a loop in the page wrapper. Three loadings of the same script means three listeners on the same button, so one click makes three requests and three messages in the inbox.

On two pages, the same form gave another symptom: two different scripts declared a variable with the same name, the browser reported a syntax error, and the entire page was left without JavaScript.

The solution was boring and therefore good: one single point of the show. All scripts go from footer, with defer and with version from one constant; bare tags in sections and side loops are removed. It was verified by measuring in the browser — exactly one request per send.

In addition, the form handler itself has been fixed. It was sending from an account that doesn't exist, was targeting a path that a global server rule was blocking with a 403, and the mailer library wasn't installed at all. Three separate failures, one visible symptom: "the form doesn't work".

07

Diacritics that disappeared from thirteen pages

Thirteen pages of the city were without our letters. Not partially — completely. "Ni" instead of "Niš", "oferajbna" instead of "windshield", "Doivotna" instead of "Dživotna", "Bonjace" instead of "Bosniaca". Someone in an earlier pass passed those files through a filter that throws out anything that isn't basic ASCII.

Returned with replacement dictionary, about four hundred and thirty corrections, not only in visible text but also in page titles, descriptions and structured data — because a misspelled company name in a schema.org block is another name for the search engine.

The trap that popped up is worth remembering. Word boundary replacement relies on the term "letter", and that term in that tool includes only basic Latin. When "Niu" is corrected to "Niš", the rule that looks for "Ni" on its own hits the same text again and makes "Nišš". The correction had to go in two passes — first the replacement, then the cleaning of the duplicated letters created by the first pass.

08

Speed

Before optimization, the site scored 67 on the PagePerformance test for phones, with the largest visible element rendering after 5.6 seconds. After: rating 92, same element at 2.9 seconds, first content from 4.4 at 2.2 seconds. On the computer 95 on 99.

There was not one big operation, but four ordinary ones:

  • Icons, grid fonts, and carousel and layout libraries were loading blocking in the header. They have been switched to loading that does not stop the plotting.
  • Five pages loaded jQuery, Bootstrap and carousel for the second time, although the header already pulls them with delayed execution. Duplicates have been removed.
  • The main cover image received a high priority loading announcement, separately for phone and desktop.
  • Images were transferred to modern formats — one of the larger ones dropped from 136 KB to 64 KB, and in AVIF format to 14 KB. The server itself chooses the format according to what the browser accepts.

The server runs Brotli compression and a cache of finished pages, and the refresh is controlled by a single constant in the header that is incremented with every style or script change. Without that, a visitor who has already been to the site sees the old look and thinks that the change was not even made.

Accessibility went from 91 to 96, for a reason that was comical until it was understood: an automated test measured contrast in the middle of CSS transitions, while the tab changes color, and reported a drop that the human eye never sees. It was solved by limiting the list of properties that are animated at all.

09

SEO and local visibility

The site carries five blocks of structured data: AutoRepair, WebSite, WebPage, LocalBusiness and a path with subpage breadcrumbs. They include the address, coordinates of the shop, working hours per day and catalog of services — that is, data that the search engine can show before the visitor even clicks.

Site ownership in Google Search Console is verified through DNS records, which is the most robust method — it doesn't depend on a root file that someone might delete the next time you transfer content.

The most interesting find was not on the site. Vhost was only listening to IPv4 even though the domain zone has an IPv6 record. Part of the Serbian mobile networks provide IPv6 first, so the traffic from those networks never went down to the real vhost. You can't see it from your own computer — the site works perfectly, while it doesn't work at all for a user of one operator. Added listening on IPv6 and closed it.

Outside the site itself, there are also profiles that feed local results. Bing ran the store as temporarily closed, at the address in Plandište — about four hundred kilometers north, due to incorrect geocoding. The data was imported from a Google profile with the correct address and status. It's not as small as it seems: Bing feeds local recommendations in ChatGPT and Copilot, so a company that is "closed" there does not even exist in the answers of those tools.

On the contact page, a button has been added that leads directly to the form for writing a Google review, next to the button for opening the map. A satisfied customer who has yet to find a place to leave a review is a customer who won't.

10

Cookies, legal texts and security

The site has a cookie bar with two choices — accept and necessary only — and that choice is remembered and respected on the next visit. Analytics works with consent management in a mode where pre-measurement is turned off until the visitor consents. A banner that only offers an "accept" button is not a banner, but a formality.

The privacy policy and terms of use were written for this store, not copied. They state exactly what is collected through the form — name, phone, email, vehicle data and description of the defect — that the online offer is indicative until the vehicle is viewed, that the deadline for responding to complaints is eight days in accordance with the Consumer Protection Act, and that the court in Leskovac is competent for disputes.

On the server side: an A+ rating on the SSL Labs test, a domain on the must-encryption list built into browsers, eight security headers, and a CAA record in DNS that allows only one authority to issue certificates. The latter is five minutes of work and prevents a scenario where someone else issues a valid certificate for someone else's domain.

All pages pass the W3C validator without a single error. This was achieved by boring work — moving styles from the body of the page to separate files, correcting elements that by specification cannot be inside each other, and adding titles to the frames with the map.

11

Outcome

What the client received

A site on its own domain, written in PHP, without WordPress and without plugins that require updates every month. There are no monthly platform subscriptions and no components that break on the next update.

Practically, the day looks like this. A driver who discovers a cracked windshield in the morning finds a phone number in the top corner and calls. A customer who prefers not to call completes a five-step quote request and it arrives in the shop's inbox with the make, model, chassis number and picture of the crack — enough to answer with a price, not a question. Whoever searches for "auto glass Vranje" comes across a page specifically about service in Vranje, not the homepage that deals with everything.

Separately from the public site, the same shop also uses an internal system for invoicing, inventory, appointments and its statutory sales ledger. It is behind the login, has three levels of access, and is not part of this site — the visitor never sees it. It is mentioned here only to make it clear what is a public site and what is not.

The site is still under active maintenance. What is changed is changed on the live site, with a backup copy before each change and a check in the real browser after it — because this project has already shown that the page can return a technically valid response while showing no content at the same time.

FAQ

Frequently asked questions

Why is there no price list for glass replacement on the site?

Because it would be incorrect. The price depends on the model of the vehicle, the version of the glass, the sensor, the heater and the camera behind the rearview mirror — two models of the same year can have different glass. Instead of a price list, there is a form that collects the make, model, year and chassis number, so the real price is given based on that.

Why does ADAS calibration have its own space on the website?

Because drivers ask for it as a separate service. Modern vehicles have cameras and sensors attached to the windshield, and after every glass change, these systems must be recalibrated to work properly. Whoever is looking for it, types that very term — so there must be a page that deals with it, and not a sentence at the bottom of another.

Why separate pages for thirteen cities?

Because people type the name of their city into the search, not the name of the shop. The page for Vranje talks about going out to the field to Vranje, the distance and time of arrival — that is, about what the visitor is interested in. They are not copies of one page with the name of the place replaced, because such pages are recognized by the browser and taken down.

Can the owner change the content himself?

This site does not have a CMS panel — changes go through us. It was a conscious decision: the content of an auto glass shop changes infrequently, and the panel would bring a constant obligation to update and an additional surface for attack that is not here. When a new service or a new city is needed, it's a half-hour change.

Why PHP and not WordPress?

Because of maintenance. A WordPress site with a theme and five or six plugins requires regular updates, and each one is a potential bug or loophole. There are no plugins that can fail, and the site is easy to move — the code and content are on the server and can be copied.

Does the site work properly on the phone?

It works, and that was a requirement from the beginning, because most of the visitors come on a phone and from a mobile connection. After optimization, the main homepage content renders in about three seconds on the phone test, and the phone number and offer button are in the header on each page.

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