Website2026-08-21

Trubači Stars — trumpet orchestra site for celebrations throughout Serbia

The orchestra that plays at celebrations, baptisms and birthdays does not sell a product from the catalog. The customer calls on the phone and asks two things: are you free on that date and how much does it cost. The entire site is built around those two questions — one hundred and five pages, no form and a number that is always at your fingertips.

Homepage of the Trubači Stars site with the phone number in the hero
Homepage — name of the orchestra, phone number and way to the gallery right at the top
Client
Trubači Stars (Stefan Tenor)
Activity
Trumpet orchestra for celebrations and weddings
Area
Leskovac, Niš, Belgrade — all of Serbia
Type
Multi-page site, 105 URLs
Technologies
PHP 8.3 · nginx · shared includes · JSON-LD
Site
trubacizaslavlja.rs
Status
Live site, under active maintenance
Technology
PHP 8.3 · nginx + FastCGI keš · Deljeni includes · JSON-LD schema · Self-hostovani fontovi
01

Problem and context

What do Trubači Stars do

Trubači Stars are a trumpet orchestra from Leskovac. Led by Stefan Tenor, the line-up adjusts to the occasion — from three to eight musicians, with trumpet, tuba, drums, tenor horn and baritone. The website states that the orchestra has been playing for more than fifteen years and has over five hundred performances; those are their numbers, not our measurement.

The job is seasonal and tied to the calendar. Celebrations, baptisms, birthdays, graduations, send-offs to the army, serenades, engagements, anniversaries, bar openings, New Year's celebrations, funerals — and weddings, which are a whole part of the story. Every occasion has its own custom and its own repertoire: St. George's Day is not played as a farewell, and the celebratory rising does not look like a round at two in the morning. The seat is in Leskovac and the Jablanički district, but the orchestra travels all over Serbia, and transportation is included in the price.

This is where this business differs from a store. No shopping cart, no order, no catalog with a "buy" button. There is a date that is either free or not, and a price that is negotiated. The site therefore does not have the task of selling — it has the task of bringing a person who is looking for trumpet players in his city, for his opportunity, to a phone number in as few steps as possible.

Section about the orchestra Trubači Stars
Section "More than music - Tradition and passion"
02

What needed to be solved

The site was not created as a single task but as a series of passages through the year 2026. Each started with a measurement, not an assumption, and each found something that cannot be seen from the outside:

  • A contact form that was sending empty. The form on the contact page was targeting a file that does not exist on the server — the server was returning a 404, and the request was getting nowhere. How long she worked like that cannot be determined. Later, the same form, when it was fixed, printed a raw JSON response to the user instead of a message that the query was sent.
  • Two domains of the same owner competing for the same queries. The owner also has a sister domain. Both offered weddings and celebrations, the identical H1 stood on sixty city pages of both sites, and the only genuine inquiry from the form arrived on this site — and that was for a wedding.
  • A rating that didn't exist. In the structured data, there was an average rating of 5 out of 127 votes, with no displayed reviews covering it and no Google profile behind it.
  • Layout shift on first opening that the Google lab didn't see, but the real browser did.
  • The number in the advertisement and the number on the website were not the same. The orchestra has two lines, and the advertisement led to one, the website to the other.

In addition to that, there was a clear request from the owner: focus on the call and message, the form to hide. For him, the phone is a work tool, and an inquiry that arrives on his e-mail and waits for half a day is a wasted appointment.

Four steps of booking and overview of services on the Trubači Stars website
How it works — four steps from invitation to performance, then music for every occasion
03

Structure — 105 URLs in three layers

The sitemap contains 105 URLs and all are live pages, not generated empty content. They are divided into three layers.

The core is six pages that people open from the menu: home, about us, services, gallery, price list and contact. The homepage is long and it works that way on purpose — from the hero with a phone number, through the four steps of booking, to instruments, a list of opportunities, impressions, a list of cities and the most frequently asked questions.

Occasions are twenty-seven pages, one for each occasion: celebration, christening, birthday, jubilee, graduation, serenade, engagement, party, funeral, bar opening, send-off to the army, May Day, New Year's Eve, and even individual holidays - St. Nicholas' Day, St. George's Day, Arandjelov's Day, St. John's Day, Mitrov's Day, St. Sava's Day. They are accompanied by guides that are not for sale: celebration customs and music, repertoire for celebration, wedding repertoire.

Cities are sixty different, from Belgrade and Novi Sad to Bujanovac and Bajina Bašta. It is the layer that brings the most arrivals from the search, because trumpeters are wanted locally — a man from Pirot does not type "trumpet orchestra Serbia" but "trumpeters Pirot".

It's all held together by seven shared PHP files in includes/ — header, navigation, footer, call to action, and landing page template. One change in head.php reaches all 105 URLs. Without that, every fix would be a script over a hundred files, which is exactly what the sister site went through that includes/ didn't have.

Trubači Stars on the phone
Same title on phone
04

Two domains, two intentions

In August, the client asked for a third domain, in order to "rank better". Instead of doing that, it measured what the first two do. In fourteen days: this site 167 organic clicks, sister twenty. For its sister Google, it didn't even have data on real visitors — Google's own confirmation that the site had no traffic. And the most important thing: for wedding queries, Google ranked this site, not the domain that was created for weddings.

A third domain would repeat the same error. A separation of intent was done instead. Thirteen celebratory pages that stood on the wedding domain were transferred here, and then the entire wedding content — with 301 redirects from the old URLs, so that none of the already acquired rank is lost. The sitemap grew from 92 to 105.

The sister domain was then built from scratch as something completely different — a site focused on one city, with its own structure and its own purpose. A separate study is written about him: Trubaci Belgrade. Only one thing is important here: two sites of the same owner no longer compete with each other, but cross links.

A detail that almost brought down the entire broadcast: the server had already had five redirects in the opposite direction. If they remained, the new 301 chain would create a loop and both addresses would stop working. They were removed before the new rule was released.

05

Call instead of form

There is no contact form on the entire site today. That's the owner's decision, and it's the right one for this business: the man who plans the glory for next Saturday won't text and wait for an answer, but calls the next person from Google results.

Instead of a form, the site has five ways to the phone and they are all the same number: a golden button with a number in the header, a floating call button on each page, a sticky strip at the bottom of the phone screen with a choice of call / Viber / WhatsApp, a button in the hero and a number in the footer. On contact page there are both lines of the orchestra, working hours and location. The primary number since the end of July is 061, the same one that is in the Google ad — before that, the site led to one line and the ad to another, so it was not known where the call was coming from. The replacement went through 992 places in the code.

In order to know how many calls the site brings, its own counter has been added: a click on any tel: link sends a beacon to /api/track-call.php, which records the time, path and type of the button in the log outside the webroot. No cookies, no IP address, no personal data. Google Analytics works in parallel, but only after the visitor agrees — cookies go by Consent Mode v2 with default rejection.

When forms are deleted, their server handlers and the dead JavaScript that sent them are also deleted. All that remains is the password form on the maintenance page, which has nothing to do with contact.

06

A price list that explains the price instead of hiding it

The most common question in this industry is the price, and the most common answer from the competition is "call us". That's why price list of trumpet players was created as a separate page that explains the mechanism.

The three packages are displayed both as cards and as a comparison table, with three columns: performance duration, number of musicians and for which occasion the package is intended. Below that are six factors that drive the price — distance from Leskovac, duration, number of musicians, day of the week and season, type of event, and special requirements such as learning a new song. Then the method of payment, then the guarantee, then the ten most frequent questions.

The table is intentionally without numbers per package, because the orchestra does not have them — the price is negotiated. What the page provides is a framework and a reason: a person knows what moves the price before picking up the phone, so the conversation starts with the concrete, not with guesswork.

That table is also an internal canon. The same three items—duration, number of musicians, occasion—must match wherever they are mentioned. Previously, four identical price cards were pasted on 74 landing pages, byte for byte of the same, and competing with the price list page itself in the search. They were removed from all but the one where prices are the topic, and in their place came a localized note and a link to the price list.

07

City pages — the same mistake repeated sixty times

The city pages were made from a template, and there arose a problem that no automatic test reported: the generator stuck the suffixes on the nominative. On the website it was written "in Šabac" instead of "in Šabac", "in India" instead of "in Inđija", "to Ćuprija" instead of "to Ćuprija", "Questions from Zrenjanin" instead of "Questions coming to us from Zrenjanin".

Total 191 places on 58 pages. For a visitor from that city, it's the first sentence he reads and the only impression he needs — the site is a foreigner who doesn't know the name of his city. It has been fixed with a case table for all sixty cities, with the protection of handwritten titles that were already correct, such as "Questions that Belgraders most often ask us".

The same type of error was in the page titles: Indija instead of Indjija, which is the name of the country and not the city in Srem, so Knazevac, Sid and Vrnjacka Banja without diacritics. The title is what Google shows in the result — no savings there.

The trap that was learned from this: mass replacement according to the form trubaci-* also affected non-city pages, so the page about trumpeters for glory and similar ones had to be checked separately. After each group change, there is a check on the pages that do not fit into the template.

08

Removing an unverified rating

In the structured data of the site, there was a rating of 5.0 based on 127 votes. On 76 pages of this site and 82 pages of the sister site — a total of 158 places. There wasn't a single featured review covering it, nor a Google profile, nor any verifiable source behind it.

Google treats it as untrue structured data and the penalty is not a warning but the removal of rich results for the entire domain, manually and without a deadline. The rating has been removed from all 158 pages. Along with it, the visible statement "5/5 customer rating" from 155 pages was removed, and in its place came the fact that can be checked from the price list: the band has from four to eight musicians.

A detail that made the job longer than it looks: the rating was written on two sites in two different forms — as JSON text on one and as a PHP string on 47 pages of the other. One search expression only catches one shape, so the first pass left half untouched, and the file-by-file check lied that it was clean until it checked what the server was actually serving.

Later, two manually written Review blocks with fictitious names were also taken down. The impressions given by the owner remained on the site as his text, without a single star and without claiming an average — because an impression is an impression, and a rating is a data that someone has to measure.

09

A shift that was only visible on a cold visit

This was the most difficult performance issue in the project. Google's tool was reporting a layout offset of 0.002 for the header — great. A cold-cache visit in a real browser on a desktop returned between 0.21 and 0.58 — bad. Both measurements were correct.

The cause was not the font itself. The three buttons in the hero are in all caps, with the phone number and spaced letters, and the row sits directly on a wrapping threshold. Until the real font is loaded, the text is rendered with a fallback, and the fallback was wider than the real one — a row of 866 pixels in a container of about 860 pixels. The buttons wrap onto a second line, the hero grows, the font is loaded, and everything jumps back.

The amplifier was a decoration: the decorative layer above the hero was twice the hero’s height and sized relative to its frame, multiplying every height change by two. The first attempt at a fix—widening the fallback font—made matters worse, as the row became even wider.

The fix was based on measurements: fallback font with size-adjust: 95% so that it is always narrower than the real one and never wider, font-display: optional on all eighteen font-face declarations, decor related to window size instead of hero, and asynchronous loading of fonts. The homepage dropped from 0.578 to 0.002 on the desktop and from 0.188 to 0 on the phone, the price list from 0.138 to 0, the city page from 0.333 to 0.004.

The rule that came from this into our process: the fallback font must be narrower than the real one, never wider, and accepting the fix is a cold visit with no layout jump at either tested width. Google today reports LCP 1553 ms and CLS 0 for this domain from the data of real visitors.

10

SEO, schema and machine-readable content

Each of the 105 pages has its own title, its own description and its own canonical URL. After the last pass, there are no duplicate titles, no duplicate descriptions, no phone pages, and no pages that have been hidden from indexing. Sitemap matches canonicals one-to-one.

Structured data covers LocalBusiness, MusicGroup, Organization, WebSite, breadcrumbs and answer questions — fifty-three blocks, all correct. Address, coordinates, working hours, area of work and profiles on Instagram and YouTube are in them, because for a local query Google is looking for exactly that.

For appropriate engines, not just browsers, llms.txt has been added, and robots.txt specifically allows GPTBot, ClaudeBot, PerplexityBot and others — with this kind of content, where every occasion has its own side with customs and repertoire, being cited in the answer is worth as much as being in the results. Every change is reported through IndexNow, which covers Bing and Yandex; Google goes at its own pace.

One thing is intentionally left "wrong" here. Titles of the homepage, page of services and page for Leskovac are longer than the recommendation and every audit reports them. Those three sides rank, and the title that ranks is not affected by the recommendation from the tool. It is written so that the next pass would not "fix" what it is doing.

The rest is what cannot be done without the owner: Google Business Profile does not exist, and for local queries it is the strongest leverage that remains unused.

11

Outcome

What the client received

One site that holds both intents, 105 URLs that don't hijack each other, and a sister domain that does its job instead of repeating the same one. No platform, no monthly subscription, no plugin that breaks at the next update — plain PHP and nginx on the server, code in git history, backup before every change.

Measurements after the last pass: all pages respond with 200, zero dead links, HTML without a single error according to W3C validator, on desktop 99 to 100 for speed and 100 for accessibility, good practice and SEO, on phone 100 for accessibility, good practice and SEO with speed in the upper part of the scale. Domain mail has a signature, SPF and DMARC, and HTTPS is on Google's preload list.

Practically, a day looks like this: someone from Kruševac types "trumpers Kruševac", opens the page of his city, sees the number in the header and sticky tape, calls and makes an appointment in the same conversation. Clicking on the number is recorded in the log, so after a month it is known how many calls the site has received and from which pages.

The site doesn't have an edit panel, and that's a conscious decision — content changes rarely, and when it does, it changes through code, with a live check after every release. What's open is open with the owner: a profile on Google Maps, videos from performances under one YouTube account, and impressions that should be replaced with real reviews. These are things that cannot be written for him.

FAQ

Frequently asked questions

Why does the orchestra have two sites and not one big one?

Because the owner already has two domains and both have search history. Merging into one would throw away everything the other domain had acquired. Instead, they have separate intentions: this site covers the celebrations and the whole of Serbia, a sister city. The third domain, which the client requested, was not created — the measurement showed that it would repeat the mistake of the second one.

Why is there no contact form on the site?

Because the owner asked for it not to exist, and because the numbers confirm it: during the entire time the form was working, one native-like app arrived. A man looking for buglers for next Saturday calls on the phone. Instead of a form, the site has five ways to reach the number, plus Viber and WhatsApp.

Why is there no star rating on the site?

Because it would be made up. A rating in structured data must be backed by real, verifiable reviews; the one that was caught had none. Google penalizes this by removing rich results for the entire domain. When the orchestra collects real reviews on the Google profile, the rating is returned with the source behind it.

Can the owner himself change the content?

No, and it is intentional. Content rarely changes on a site like this — a new opportunity, a new city, a text correction — so the editing panel wouldn't earn its keep. Changes go through the code, with a backup before and a live check after.

How many pages can a site like this handle?

One hundred and five is the current state, but the limit is not technical. All pages share seven PHP files, so one change in the header reaches all at once. The limit is content: the page only makes sense if there is something concrete to say about that city or that occasion.

Does the site look right on a phone?

Yes, and that's where most visitors come from. The phone also has a sticky strip at the bottom of the screen with three buttons — call, Viber, WhatsApp — so the number is never more than one touch away, no matter how far the person has scrolled.

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