Website2026-08-21
FOX Models — model agency site in dark 3D version
The website is a shop window for a modeling agency, and the shop window is people. This version places photos in a 3D ring that rotates as you scroll, and everything below that is a simple quick catalog: boards, profiles with measurements, and a signup for new models. Our subdomain, our project, open for verification.
- Client
- FOX Models, model agency
- Activity
- Model boards, scouting, booking
- City
- Belgrade
- Type
- Multi-page site with 3D scene (our project)
- Technologies
- Next.js 16 · React Three Fiber · three.js · GSAP · Lenis
- Scope
- 24 static pages, 17 model profiles
- Technology
- Next.js 16 · React Three Fiber · three.js · GSAP + Lenis · TypeScript
Problem and context
About FOX Models and this concept
FOX Models is a modeling agency from Belgrade. He leads the women's and men's board, scouts new faces and places them with fashion houses, magazines and brands — from the first test shoot to the campaign. The job of the agency is to bring the person in front of the client who chooses, and the website is the first place that client looks: he opens the board, scrolls through the list, remembers two names and writes on booking.
To make it immediately clear whose this is: models1.svilenkovic.rs is my subdomain and our own project. The site was created as a redesign proposal for the agency, it is alive on our server and serves as an example of work. The names, measurements and part of the photos are demo content that stands in one place in the code — when switching to the agency's real domain, it is replaced by data from its database.
Therefore, the text below does not make any claims about traffic, inquiries or campaign results. There is only what can be opened and checked: how the site was put together, why the 3D scene is where it is, where it was difficult and what the agency would get if it took it on its domain.
Two versions for the same agency
For FOX Models there are two sites, not one. This is a dark version with a 3D scene. The other is classic, light, without any 3D lines — it is written about in a separate study, FOX Models, classic version, and it lives on another subdomain. Same content, same agency, two completely different impressions.
The reason for two versions is simple: in a fashion agency, the taste of the owner decides more than any list of functions. Instead of guessing, I prepared two contrasting directions. One is a restrained grid of unembellished portraits, in the manner of Scandinavian agency sites. The second is this — black background, cyan accent, photos that rotate in space as you scroll.
When the agency looked at both, the message was that the cover should be simpler. That feedback was picked up by the classic version and its home page was reduced to a clean grid of the entire setup. This version was intentionally left at the opposite end, as an answer to the question of how much atmosphere that the agency's site can handle and still be usable.
What needed to be solved
A modeling agency site is a people directory. It sounds like a regular gallery until you sit down to put it together — then it turns out there are four requirements that push each other:
- A photo is a product. Anything that stands over the image, cuts it or stretches it works against the site. Framing must be correct, at all widths, for both portrait and square.
- Boards are not looked at, they are flipped through. The customer does not read the descriptions, he scans the faces and stops at one. The grid must load quickly, and basic data must be within reach without opening a profile.
- Each model is its own page. Booking is sent from one address that is forwarded to a colleague, opened on the phone and shared. The profile must have its own URL, its own title, and its own picture for preview in messages.
- Registration of new people is another workflow. Scouting arrives from unknown people, on a phone, with two to three photos. It is not the same form as booking and it must not be the same.
There was also a requirement that pushed the whole project into 3D: an agency that works with fashion houses must not have a site that looks like a local catalog. The first screen must make an impression. But a photo-eating or scroll-blocking impression is worse than none — so the scene had to be the atmosphere behind the content, not the obstacle in front of it.
Site structure
The structure uses six page types. Homepage, women's board, men's board, model profile, editorials and contact with application. The build outputs 24 static pages, because each model gets its own: currently there are seventeen of them, twelve in the women's and five in the men's board.
The homepage unfolds in five stages. First the title over the 3D scene, then a strip with names of brands and publications associated with the agency’s work, then a selection of faces from the women's board, then editorial covers and campaigns, then two large entrances to women and men's board. At the bottom is a short text about the agency and a call for new models. Each of those sections has its own link to the full list, so no one gets stuck on the homepage.
The addresses are clean and in Serbian: /zene, /muskarci, /editoriali, /kontakt, /model/mina-s. No file extensions, no parameters, no query-string identifiers. The server solves them through try_files, so each of them has a real 404 if there is a typo.
3D photo ring
The scene is one fixed layer behind all the cover content. It revolves around a ring of nine portraits, placed in a circle and facing the center, with a field of eighteen hundred points that gives depth. The camera is not static: as you scroll, it moves closer to the ring and rises at the same time, and the ring lowers and speeds up the rotation. Moving the mouse tilts the entire assembly a few degrees.
All that movement is driven by one value — what percentage of the page you scrolled. No timer, no self-paced animation. If you stop, the scene stops with you. Therefore, there is no moment where the content and background are doing two different things.
A detail that is not noticed, and without it the whole effect falls: photos do not stretch in 3D. Each texture is cropped to the aspect ratio of the plate in the ring when loaded, using the same principle that a grid image fills its frame. Without it, a wide picture on an upright board would look like a distorted face, which is the only unforgivable mistake on a modeling agency's website.
The scene exists only on the cover. Internal pages do not import it, so even part of the code with the 3D library on them is not downloaded — the board and profiles are pure content. On the cover, the scene is loaded only in the browser, after the main content, and never blocks the display of the text.
Whoever has turned off animations in the system gets a static image: the ring stands still, the camera does not move, and the scene stops being drawn in a loop. The drawing resolution is limited from above, so phones with dense screens don't need to draw more pixels than makes sense.
Boards, Search and A-Z
Board is a grid of cards with photo, name and city. Hovering over the card over the image reveals a thin layer with basic measurements — for women, height, shoe size and number, for men, height, chest with waist, and suit number. That is exactly as much as the customer needs to decide whether to open a profile.
There are three tools above the grid. Filter by board — Main Board, Development, Commercial, New Faces and domestic models. Search by name that works as you type. And A-Z index with Serbian alphabet, including Ч, І, Д, Ш and Ж, in which letters without any model are visibly extinguished and cannot be clicked. The number of displayed models is right next to the search and changes on the fly.
The faded letters are a small thing that is often overlooked. An index where you click on a letter and get a blank page is worse than an index that doesn't exist, because the visitor thinks the site is broken. Here the letter either leads somewhere or is clearly dead.
The male board on /muskarci works according to the same logic and with the same components — one implementation, two genders, without copied code that diverges later.
Model page
The profile is divided into two columns: a photo gallery with on the one hand, data on the other. The data goes as an orderly list — height, chest, waist, hips or suit, shoes, hair, eyes — above them is a board mark, below them two strokes: Booking inquiry which leads right to the form and a link to the agency's Instagram account.
Under each profile are four people from the same board and a link to the entire board. It's the only navigation that really works on a site like this: a person who has opened a profile almost never looks for that particular face, but the face of that guy.
Each page of the model has its own title, description and canonical URL, and carries structured information about the person and the path to the board through which they were reached. When the link is pasted into a message or email, the name, city and main photo appear — not the bare domain name.
Editorials
Page Editorijali is a wall of covers, campaigns and shoots, with the name of the magazine or brand under each one. A click opens the lightbox over the entire page.
The lightbox is written so that it can also be controlled by the keyboard: the arrows scroll, the exit key closes, the focus remains trapped inside the view while it is open and returns to exactly the image it started from. On the phone, it scrolls by swiping. It's not a decoration — a gallery that can't be closed with a button is a gallery that some visitors exit by closing the tab.
Photos sink softly when they arrive, instead of popping. Since on the real domain the images arrive from the agency base and can be delayed, that transition is intentionally left wherever the image is rendered from the data.
Registering new models and protecting against fake scouts
The contact page has two separate parts. On the left is the application form for new models: name, age, height, city, Instagram, email, message and a photo field where images can be dragged with the mouse or selected by touch. It asks for two to four photos without makeup, in natural light, and it says so above the form — because that's the only format that really benefits the scout.
On the right are the addresses for booking and for scouting, the city and the Instagram account. Below them is a warning that is worth as much as anything else on the website of the modeling agency: scouting is always free, the agency never asks for payment to join the board and does not respond through unofficial accounts. Fake scouts on social media are a real problem in this industry and the only defense a site can provide is to clearly state what real communication looks like.
Open about this implementation: in it, the form only works in the browser — it checks the fields, shows a confirmation, and stops there. Sending e-mails and receiving photos is a server job that is tied up when switching to the right domain, because there the form connects to the same PHP layer that serves the images from the database. That's a deliberate limitation of this display, not an omission waiting to be noticed. The address for contact and application is on the website and leads to the real URLs of the agency.
Technical performance and speed
The site is written in Next.js 16 with React 19 and TypeScript, and the 3D part in React Three Fiber over three.js, with GSAP and Lenis for soft scrolling. What is important for working on the server: the build does not leave a running server process, but a bunch of finished HTML files. Nginx serves them directly from disk.
That decision solves three things at once. There is no Node process that can crash or leak memory. There is no application server exposed to each request because nginx serves static output directly. And there is no need to render a page separately for each visitor — everything is already made.
At the server level, there's the rest: gzip, permanent caching for fingerprinted files, a month for images, clean URLs, its own certificate, and a content policy that limits where anything can be uploaded. Fonts are loaded through the system that comes with Next, with the extended Latin set included — without it, č, ć, š, ž and đ would appear from the fallback font, and headings would mix two typefaces on the same line.
Two places took the most time and are worth noting. First: when the 3D canvas is behind the content, the body of the page must be transparent, and the base color must be carried by the layer above it. While this wasn't the case, the scene was rendering properly and nothing was visible — a black screen over which an opaque background is rendered looks just like a non-running scene. Second: the loading of textures must be wrapped in a loading boundary, otherwise the entire scene tree can silently disappear, without a single error in the console. Neither case raises an obvious error — they are seen only by the fact that something is not there.
The rest of the behavior is common but checked: the content appears on entering the viewport, and if the script doesn't work, the noscript styles keep all content visible. Profile details and contact content move into one column below a certain width, and the horizontal overflow is cut at the document level, so the layout does not drift horizontally even on narrow screens.
Outcome
SEO, indexing and what the agency gets
Everything SEO is looking for is already built in. Each page has its own title, description, and canonical URL; the homepage contains information about the organization and the site; boards carry a list of models as a collection; profiles contain data about the person and breadcrumb path through the site; editorials carry a gallery. The sitemap is generated under construction and contains all pages, including each profile.
Along with this is a deliberate move that looks like a bug until it's explained: the site is closed for indexing. It shouldn't be in a search on my subdomain — otherwise it would appear as another result for the agency's name, interfering with its real site and splitting signals into two addresses. It is one line in the settings that is removed on the day of switching to a real domain, and then all of the above will start working for the agency instead of standing still.
What would the agency get? A site that opens immediately because everything is pre-assembled; a profile for each model with an address to be sent to the customer; a sidebar that filters and searches instead of scrolling to the bottom; one place in the code to hang its base, so adding a model doesn't mean calling us; and the first screen that looks like an agency that works with fashion houses, not a list.
All of this is live and can be opened on the phone and on the computer before any decision is made. That was the purpose — not to talk about the proposal, but to click on it.
FAQ
Frequently asked questions
Why use 3D on a modeling agency website?
The opening screen is the one place where this kind of site can establish its visual character, and photography is already the main content. The rotating ring uses those same photographs instead of competing with them. The scene sits behind the content and appears only on the homepage.
Does 3D slow down a site on a phone?
The scene only loads on the homepage and only after the main content — the inside pages don't download any code with the 3D library. The rendering resolution is limited from above, and whoever has turned off animations in the system gets a static image without a rendering loop.
Can the agency add models automatically?
In this version, the content is in one place in the code, because it is a display. The structure is deliberately made so that one place is replaced by a base, so models, measurements and photos go through the administration like on any other site of ours.
Why does the site not appear in Google search?
It is deliberately closed for indexing because it is on my subdomain. If it was open, it would compete with the agency's real site for its own name. The ban is one line in the settings and is removed the day the site moves to the agency's domain.
What happens after someone submits the model application?
In this version, the form only works in the browser and stops at confirmation. Sending e-mails and receiving photos are linked when switching to the right domain, to the same server layer that then also serves the model data. The addresses for booking and scouting on the contact page are correct.
How many models can this site support?
Currently, one page for each model, seventeen of them, is under construction. For a board of several hundred faces, it is switched to a database with loading in parts, while the filter by board, search and A-Z index remain the same — they were written for large boards.
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