The stays website
What the booking website does: the home page, the stays and their filters, the stay page with its calendar and reserve card, the checkout, the guest's booking page, saved stays, questions, search engines and marketing tags.
For the Full Stack package
Pages
Every page exists in English under /en and in Arabic under /ar. The website has no accounts and no sign-in. The header stays at the top of the window as a page scrolls, every form field shows an example of what it expects, and Arabic text on an English page, such as the language menu's Arabic entry, is drawn in the Arabic face.
| Page | Path | What it shows |
|---|---|---|
| Home | /en | A search attached to the hero (destination, check-in, check-out, guests), the hero stay's photographs beside the first destinations, every destination, the featured stays the host picks in the dashboard, the six kinds of place, how a booking works, a long weekend and a month as two ready-made searches, why to book direct, the questions guests ask, and a way to get in touch. |
| Stays | /en/stays, e.g. /en/stays?destination=marisol-coast&guests=2 | The published stays, with filters, sorting and pages. |
| A stay | /en/stays/cedar-house | The photographs, the facts, the reserve card, the description, amenities, times and house rules, the availability calendar, reviews, the area on a map, similar stays and a question dialog. |
| Checkout | /en/book/cedar-house?checkIn=…&checkOut=…&guests=2 | Opened from a stay's Reserve button: the guest's details, the payment method, the cancellation policy and the summary. |
| A booking | /en/bookings/<reference> | The guest's own booking, opened from the link after checkout or found by reference and email. |
| Find my booking | /en/bookings/find | A booking reference and the email it was made with. |
| Destinations | /en/destinations, /en/destinations/marisol-coast | Every destination, and one destination with its stays. |
| Saved stays | /en/saved | The stays the visitor saved, kept in their browser. |
| About, contact, privacy | /en/about, /en/contact, /en/privacy | The company's story, its details and the contact form, and template privacy copy to rewrite before going live. |
Finding a stay
- Filters for destination, dates, guests and stay type (
villa,apartment,cabin,chalet,loft,cottage), kept in the address, so a search can be shared, reloaded and walked with back and forward. Applied filters show as chips, and a phone opens the same filters in a sheet, closed with its Close button. - With dates, only the stays free for every night of
[check-in, check-out)are listed; with guests, only those that sleep that many. - Sorting by the company's own order, price from low to high or from high to low, or rating, six stays a page.
- Only published stays appear. Every price is the currency code followed by the amount, such as
USD 240 / night.
The stay page
- A gallery of one large photograph and its thumbnails, a swipe strip on a phone, and the facts: guests, bedrooms, beds, bathrooms and area.
- The reserve card prices the nights as they are chosen: the nightly rate times the nights, the cleaning fee once, and the total, from the API's quote. On a phone the total and the Reserve button stay pinned to the bottom of the screen.
- The availability calendar shows two months with five states: available, unavailable (past, or inside the stay's minimum), taken, the chosen check-in and check-out, and the nights between them.
- The description, the amenities, check-in and check-out times and house rules, the published reviews with the stay's average, the approximate area on a map (never the exact address), up to three similar stays, and a question dialog.
The checkout
- The guest's first and last name, email, phone and optional special requests, one guest count (adults and children are not split), and the payment method among those the API offers: card, PayPal or pay on arrival.
- The guest confirms the cancellation policy, which the company edits in its settings. A guest cancels free online up to seven days before the local check-in time.
- A card or PayPal booking is finished on Stripe's or PayPal's own page, so no card number reaches the website or the API. The webhook is what confirms it, never the guest coming back; until it arrives the booking page says the payment is being confirmed.
- While no processor is configured, the shipped simulator collects a card on the page itself, under the note "Test mode: no card is charged.", and settles it at once; a number ending in
0is declined. Once Stripe or PayPal is configured, the checkout offers only the methods they take, plus pay on arrival while it is on.
A booking afterwards
- The page after checkout opens the booking with a private token in its address. Later, a guest finds it at Find my booking with its reference (such as
B0021) and the email it was made with; a wrong pair answers that no booking was found. - It shows the stay, the dates and nights, the guests, the price and the payment, and what happens next.
- The guest cancels it there while it is pending or confirmed and check-in is at least seven days away; after that the page says to contact the host.
- Once the stay is completed, the guest can review it from the same page, once per booking, with a rating and a comment of 10 to 2000 characters. Reviews appear on the stay page straight away, and the team can hide one from the dashboard.
Questions to the host
The contact page and the stay page's question dialog both send a question to the host: a name, an email, an optional phone and a message of 10 to 4000 characters, and from a stay page that stay with the dates and guests chosen. Each becomes an inquiry in the dashboard, with a notification. Nothing is emailed: the guest sees a confirmation on the page, and the team answers from its own mailbox.
The checkout and both forms carry a hidden field that catches bots and a one-time token, so the same submission is stored only once, and each address may send five bookings, five questions and five reviews in ten minutes.
Saved stays
A visitor saves up to 12 stays without an account. The list is kept in the visitor's browser and never reaches the API, beyond reading the saved stays' cards.
Search engines
- Every page sets its own title, description, canonical address and the alternate language, built from
NEXT_PUBLIC_SITE_URL. A stay page uses the stay's own SEO title and description and its cover photograph for sharing, and a destination page its own name and cover. /sitemap.xmllists every public page in both languages, every published stay and every destination;/robots.txtpoints to it. A booking, the cancelled-checkout page and saved stays are markednoindex.
Analytics and tracking tags
Six networks are wired in. Turn one on by putting its id in .env (with Docker Compose, in the .env beside docker-compose.yml) and rebuilding; an id left blank loads no script.
| Variable | Network |
|---|---|
NEXT_PUBLIC_GTM_ID | Google Tag Manager |
NEXT_PUBLIC_GA4_MEASUREMENT_ID | Google Analytics 4 |
NEXT_PUBLIC_META_PIXEL_ID | Facebook and Instagram |
NEXT_PUBLIC_TIKTOK_PIXEL_ID | TikTok |
NEXT_PUBLIC_SNAPCHAT_PIXEL_ID | Snapchat |
NEXT_PUBLIC_PINTEREST_TAG_ID |
The site reports page_view and five events:
| Event | When |
|---|---|
page_view | Every route change |
view_stay | A stay page is shown |
save_stay | A stay is saved |
booking_started | The checkout is submitted |
booking_paid | A guest who arrived from the checkout sees the booking as paid, once per booking |
inquiry_submit | A question is sent |
booking_paidwaits for the payment to settle, so a card or PayPal booking counts once the webhook or the simulator has marked it paid. The same booking page opened later by reference and email is not counted, a reload never reports it twice, and a booking paid on arrival is not reported as a purchase.- If GA4 runs inside your Tag Manager container, leave the GA4 id blank, or every session is counted twice.
NEXT_PUBLIC_ANALYTICS_CURRENCY(USDby default) is sent with every tracked price, andNEXT_PUBLIC_ANALYTICS_DEBUG=truelogs each event to the browser console.- The tags load as soon as the page does. If you serve visitors in the EU or the UK, put a consent banner in front of them first.
How the website's code fits together
Included with your purchase. Sign in to read, or open it in your download.
The code's structure and the conventions to keep when you change it.