Skip to content
D. Svilenković
01Work02Services03Industries04Guides053D06Check your site07Contact

HomeWorkApartment 11/61 — Kraljevi Čardaci

Apartment 11/61 — Kraljevi Čardaci

a website for sale and rental

An apartment in an aparthotel on Kopaonik that is for sale and for rent at the same time. One page has to serve two completely different visitors: one looking for a weekend stay and one thinking about buying. All of it in two languages, with no contact form and no agency in between.

  • One-page website
  • Kopaonik
  • August 2026
  • 12 min read
  • Next.js 16
  • next-intl SR/EN
  • Tailwind
Customer
Bratislav Rajković, owner of apartment 11/61
Industry
Apartment rental and sale on Kopaonik
Area
Kopaonik, Vikend Naselje
Type
Home page with two guides, in two languages
Languages
Serbian (sr-RS) and English
Technologies
Next.js 16 · React 19 · next-intl
Website
kraljevicardaci.svilenkovic.rs
Status
Live since May 2026, on our subdomain
Home page of the Apartment 11/61 Kraljevi Čardaci website with the apartment label card
Home page — “Apartment 11/61. Kraljevi Čardaci.”, call or Viber and a card with the apartment's label

01 / 10

Apartment 11/61 and the man behind it

Apartment 11/61 is in the Kraljevi Čardaci Spa complex, in Vikend Naselje on Kopaonik, and is advertised for sale and for rent. The owner is Bratislav Rajković and everything is arranged directly with him, without an agency.

The site doesn't publish the price, availability or the apartment's amenities: the owner confirms those. The photos show the complex and its shared facilities, including a 1,500 m² spa center, not the apartment's interior, and the site says so, as well as that it isn't the complex's official website.

One thing up front, to avoid any confusion. The site lives on our subdomain kraljevicardaci.svilenkovic.rs, not on a domain of its own. The owner is a real person, the phone number on the site works, and the site has been live since May 2026. What doesn't exist is a separate domain, so the site lives with us.

Complex gallery: The mountain outside. Warmth inside.
Complex gallery — photos of the complex and shared facilities, not the apartment's interior

02 / 10

What needed solving

The request wasn't “make a website for an apartment”. It was narrower and harder than that:

  • Two visitors on the same page — a guest looking for a place to stay for three nights and a buyer considering a property don't read the same text or decide at the same pace. Both need to find what they're after without either one feeling they've landed on someone else's page.
  • Two languages, no mixing — Kopaonik gets foreign guests too. A site with half its content in Serbian and half in English is worse than a site in just one language.
  • Contact without a form — the owner works by phone and Viber. A form that sends him emails he doesn't read would be an obstacle, not a service.
  • There are no photos of the apartment — he hasn't sent any. The site had to look good without them, and without a single image that would lead a buyer to expect something they won't get.

That last point shaped more than it sounds. Early in development the site showed four photos of an apartment of the same type, as an illustration. They were removed, because a property buyer is the last person you should show someone else's room. What remained were the official photos of the complex and the spa center, and at the bottom of the page a sentence makes clear that these are photos of the complex and its shared facilities, not the interior of apartment 11/61. The empty spot where the apartment's interior should be is still waiting for the owner's photos.

Sale and rental of Apartment 11/61 section with three steps
Sale and rental — three steps to an agreement, with call and Viber instead of an agency

03 / 10

One page and two guides

The home page is a single page, and the navigation jumps to anchors: About the apartment, Sale, Gallery, Spa, Location, Questions and Contact. The order follows how people decide: first what the apartment is, and only then sale and rental, because a guest looking for a place to stay shouldn't run into a purchase offer in the first sentence.

For questions that don't fit in one section there are two guides, both also in English: one on the Kraljevi Čardaci complex (spa, restaurants, transport and parking) and one on buying the apartment. The questions are listed at the end of the home page: ten short answers, with a note that for details that change, direct confirmation from the owner has the final word.

04 / 10

Sale and rental on the same page

The section Apartment sale has, since the September 2026 redesign, served both buyer and guest, under the heading Sale and rental of Apartment 11/61. There's no descriptive text circling around the subject. Instead of a price card, there's a note that the site doesn't publish the price, availability or legal status, and three steps: an inquiry, checking the details with the owner, and arranging a viewing or a stay.

The first version gave the buyer more: a price card reading On request, a table of eight details a buyer wants before even calling (status, ownership, number of rooms, bathrooms, position in the complex, heating, furnishings and parking), and a list of what's included in the sale: furniture, appliances, bed linen, rights to use the complex's facilities, a parking space and the existing guest base from rentals, with the option for the new owner to keep renting it out.

That last item was what set the section apart from a classified ad, along with a banner reminding visitors that the apartment is for sale and rentals continue until the handover. In the redesign, the table, the list and the banner were dropped, and the site now says that all current information is checked directly with the owner.

The price is deliberately not written on the site or in the structured data. On a property website, an outdated amount is worse than an omitted one: once a number is published, it lives on in search engine caches and other people's screenshots longer than it does in negotiations.

05 / 10

Two languages, no automatic switching

The Serbian version sits at the root of the domain, the English one at /en. All content is data, not code: texts, headings, search descriptions and questions live in two translation files, so the languages can't drift apart because something was changed in one place and forgotten in the other.

Automatic switching based on the browser language is turned off, and that was a deliberate decision. While it was on, a visitor with an English browser got the English page, where some leftover texts were still in Serbian, so the whole site felt half translated. Now everyone gets the Serbian version and clicks EN themselves if they need it. Less cleverness in the system, more predictability for the person.

The leftover Serbian texts were found along the way and moved into the translations: the floor label in two places and the button text in the rental section had been hardcoded, so the English version spoke Serbian in those spots. You find them by searching the English HTML for Serbian characters and words; if anything turns up, the translation is incomplete, however tidy the page looks.

Underneath sits a trap you can't see. Setting a prefix for the default language with its own prefix map sends the root URL into an endless redirect loop, and the page doesn't open at all. The fix is simple once you know it: the default language doesn't get its own prefix map but relies on the default behavior, and then the root works while English lives on its own prefix. The site also carries hreflang tags for Serbian, English and the default variant, identical in the page head and in the sitemap.

06 / 10

3D that didn't cost the phone anything

Until the September 2026 redesign, a golden geometric loop spun in the header on desktop, built in React Three Fiber: a triple torus knot with a thin gold accent, a gentle float and a soft shadow beneath it. There was no environment map from the network, just three hand-placed lights, because that avoided loading an external lighting map that the site's security rules would have blocked anyway.

It's worth saying that getting to that scene was hard. The first version of the site was dark, with a crown and steam in the background; it was rejected and replaced with a calm, light look. Then came a rotating marble obelisk, which was also rejected as a miss. The loop was the third attempt and the first one that stayed, right up to the redesign, when the header got a photo of the complex instead of a scene. None of the three versions was technically worse than the others; the difference was whether the scene suited an apartment being sold to serious people.

Across all three versions, the same rule applied to how such a scene goes live. Before it was even mounted, the code checked whether the browser could really draw 3D graphics; if not, a calm color gradient showed in its place and nobody saw an error. Mounting was deferred until just after the page's first paint, so the 3D wouldn't steal bandwidth from what the visitor was actually waiting for. Below 768 pixels wide, there was no scene at all — on phones neither the canvas nor the library loaded. Today the 3D library doesn't load on any device.

The snow falling across the page wasn't 3D but about twenty plain elements with a pure CSS animation and a random drift for each flake; on phones there were half as many. Zero work per frame for something that was only decoration anyway. In the redesign the snow went too.

07 / 10

Motion that doesn't shift the content

Jumps to sections are smoothed, and sections reveal themselves as they come into view. All the motion runs on small pieces of custom code rather than a big animation library: reveal on entering the viewport, parallax synced to animation frames, a reading progress bar and a header that gets a dark background once the page scrolls.

The reveal on entry has a safety net. Content is hidden only once the script takes over the animation, so without it nothing stays hidden, and with reduced motion everything shows at once. An animation that forgets to start is a blank page, and a blank page is worse than a page with no animation.

In the first version, everything was animated with movement, not opacity. The reason was specific: an element sitting off-screen at zero opacity fails the automated accessibility check, because the tool measures the computed style and sees text with no contrast. After the redesign, sections come in with both movement and opacity, but they're hidden only once the script takes over the animation, so the content in the HTML is visible from the first paint.

At the bottom right is a call button that appears only after the visitor scrolls past the first screen, and it expands into call and Viber. While it's hidden, it uses an attribute that removes it from both the accessibility tree and the tab order, because a wrapper that contains buttons must not just be marked as hidden for screen readers; that's an error the checker catches immediately. Layout shift on load is zero on both versions, on desktop and on mobile.

08 / 10

Speed, contrast and one concession

On desktop the site scores a hundred out of a hundred in all four categories of Google's test, with the largest element rendered in under a second. On mobile, performance in the first version hovered around eighty, and the mobile PageSpeed score on October 16, 2026 was 99. Accessibility, best practices and SEO stay at a hundred.

That first mobile number wasn't an oversight but a concession, and it's only fair to say why. The headings use a variable serif font with two axes, which weighs about two hundred kilobytes and on its own pushes up the time to render the largest element. That font is what gives the site the look it was made for. Replacing it would fix the number and spoil the impression, so it was kept on purpose, and the options for trimming it later, should that ever be decided, are known and written down.

Contrast was a job of its own. In the first version, the gold on a light background had a ratio of three and a half to one, which is too low for text, so gold stayed purely decorative and the lettering used a darker variant at eleven to one. The same check also failed the standard blue for links, which was a hundredth below the threshold, so it was replaced with a darker one. After the redesign there is no gold left in the palette, and links take the color of the surrounding text. The document's language attribute is set in the layer that knows which language is in use, because the root doesn't.

Both versions pass W3C validation without a single error. The last one left over involved the map: the map frame sat inside a link, which isn't allowed. It was solved by placing the link as a transparent layer over the map, which didn't take clicks itself; for the visitor nothing changed, and a click anywhere on the map opened Google Maps. After the redesign the embedded map is gone: the location section has a photo with a pin and a button that opens the location in Google Maps.

One fault showed up neither in the code nor in the speed. The domain had a published IPv6 record for an address the server doesn't own, so visitors on IPv6-only connections ran into silence. Dual-stack users were saved by the browser falling back to IPv4 after a short wait, which is why a problem like this can go unnoticed for years. It was fixed in DNS, on every host in the same group.

09 / 10

Schema that knew the difference between selling and renting

On this site, structured data did more work than anything else, because Google had to understand that one property stands in two different relationships at once. The graph had eight nodes: the apartment itself with coordinates, amenities and the fact that it sits inside the complex; the complex as a resort with its category and awards; the lodging business; the owner as a person; the real estate listing; the website; the questions and answers; and the breadcrumb trail. After the September 2026 redesign it has seven: the apartment inside the complex, the complex as a resort with coordinates, the address, the owner, the website, the site's author, and the questions and answers.

The key detail was in the offers attached to the apartment. Instead of one generic offer there were two, distinguished by business function codes from a vocabulary Google understands: one said the property is for sale, the other that it's for rent. That's what a search engine uses to choose which kind of rich result to show: real estate or lodging. In the redesign the offers were dropped from the graph, so today's schema describes the apartment, the complex and the owner, without terms of sale or rental.

The ten questions and answers aren't copied into the schema by hand; they're generated from the same translation file that prints them on the page. That removes the most common mistake: an answer changed on the page while the old one stays in the structured data. Ratings and reviews weren't added, because there aren't any; a made-up rating is the fastest way to get a page dropped from the results.

Titles and search descriptions were shortened in one pass: the Serbian title from a hundred to sixty-three characters, the description from three hundred to a hundred and fifty-six, and the English ones similarly. Google cuts off a description that's too long, so the last third of the work had been invisible. The phone number was taken out of the title, and the page's main heading gained the phrase Kraljevi Čardaci, which until then had appeared only in a small overline.

The image shown when the link is shared on social networks was completely broken and returned a server error. The cause was two traps in the tool that draws that image: one way of displaying elements isn't allowed, and every element with more than one child must explicitly state how it lays out its children. On top of that, execution was moved from the edge runtime to the regular one, because on a self-hosted server the edge runtime is unreliable. Now the image works in both languages, with Serbian letters.

10 / 10

Contact without a form, and what the owner ends up with

The contact section has no form and won't get one. It has the owner's name, phone number and Viber, and the same calls to action are spread across the page: in the header, in the hero, in the sale section and in the floating button. The owner doesn't check his inbox every day and said so up front, so a form would just be a place where inquiries sit quietly.

For a site with two contact channels, that means something unexpectedly pleasant: there's nothing to maintain. No database that can go down, no mail that can end up in spam, no admin panel to log into. The price of that choice is that the content doesn't change by itself: the texts live in translation files and are changed by editing, not through an admin area. For a single page updated once or twice a year, that's cheaper than an admin panel that would have to be built and maintained.

For the same reason, the site also links to the same owner's other apartment in the center of Kopaonik. The link goes both ways, so the two sites stand as one whole rather than two unrelated listings. A guest who came for the larger apartment but found the smaller one doesn't leave empty-handed.

Analytics runs with consent under the Consent Mode v2 standard: until the visitor accepts, measurement stays off, and the cookie banner offers both rejection and settings. The certificate is on automatic renewal, and the security headers are set in full and only once, with no duplication between the application and the server.

What's left is what we can't do in the owner's place, so let's put it in writing. Technically nothing holds the site back in search, but until ownership is verified in Google's tools and the sitemap is submitted, a young subdomain gets indexed slowly. Photos of the interior of apartment 11/61 are still missing, and only the owner can take them. Everything else is in place and waiting on those two steps.

On a phone

The same site, in your hand.

Most visitors come from phones, so the layout, buttons and images are arranged for the small screen first.

Apartment 11/61 — Kraljevi Čardaci on a phone

Questions

What clients ask.

Why is the main content on a single page?

Because that's all the content calls for: one apartment, one owner, one complex. The navigation jumps to anchors within the home page, and only the two guides, on the complex and on buying, have pages of their own.

How does one page serve both a buyer and a guest?

Through the order of content and a single contact. First comes what the apartment is, and only then the sale and rental section, which sends both kinds of inquiry to the same number and states clearly that the owner confirms the price, availability and terms.

Why doesn't the site have a contact form?

Because the owner works by phone and Viber, not email. A form that sends messages to a rarely opened inbox helps nobody. The phone number and Viber appear in several places on the page, including a button that follows the visitor while scrolling.

Does the site still have a 3D scene?

No. The scene from the first version, which loaded only on desktop and only after the page's first paint, was removed in the September 2026 redesign. A photo of the complex now carries the home page, so the 3D library doesn't load on any device.

Can the owner change the text and the price himself?

Not through an admin panel, and that's a deliberate decision. The content lives in translation files and is changed by editing the site. For a single page that gets updated once or twice a year, building and maintaining an admin area would cost more than the edits themselves. The apartment's price is deliberately not written as a number anywhere; it's available on request.

What does a site like this need to show up in search?

Technically everything is in place: titles, descriptions, structured data, the sitemap and language tags. What's left is verifying ownership in Google's tools and submitting the sitemap, which the account owner does. Without that, a young subdomain gets indexed slowly, however clean it is.

Related projects

From the same field.

Next projectDiamond Lux KopaonikOne-page website · Kopaonik

→Contact

Have a project? Write to us.

Four short questions, about a minute of your time. We reply within 24 hours.