GxA Solutions
Back to portfolio
Web

GScopy website built with Next.js on our own VPS

Bilingual website for GScopy built with Next.js 15 and Tailwind 4, with trial downloads served from a Hetzner VPS.

GScopy website built with Next.js on our own VPS

We built the presentation website for GScopy, our desktop application for medical clinics, at gscopy.gxasolutions.com. The site presents the platform and each application, has pricing and contact pages, and hosts the 7-day trial download for Windows and macOS.

The GScopy home page with the headline about one application per specialty and the buttons See the applications and Download TRIAL

Next.js 15, Tailwind 4 and framer-motion, with statically generated pages

The stack is:

• Next.js 15 with the App Router and React 19.1 • TypeScript 5.8 • Tailwind CSS 4.1, configured through @theme in globals.css • framer-motion 12, with our own primitives (Reveal, Stagger, LiftCard, CountUp, FadeIn) that respect prefers-reduced-motion • Geist fonts through next/font, so there is no external request for them

All content pages are statically generated.

Applications are data, not pages

The registry in products.ts describes each application: its slug per language, status (available or coming-soon), accent color, file names and versions. Navigation, sitemap, JSON-LD, product pages, downloads and pricing are all generated from it. For a new specialty I add an id, a registry entry and the texts in both dictionaries, and TypeScript flags any missing translation.

The GScopy Endoscopy page with the headline about the program for your digestive endoscopy clinic and the app mockup

Romanian and English, with translated slugs only for products

Products have different addresses per language, /ro/endoscopie and /en/endoscopy, while the other routes use the same slug in both, so existing URLs stay stable. Each page has its own metadata, hreflang for RO, EN and x-default, a canonical URL, and the OpenGraph image is generated at /api/og. In July 2026 we moved from a single product to a platform with one application per specialty, and the old /features and /download now redirect permanently (301) to the endoscopy page.

Each application has its own JSON-LD

The site publishes Organization, WebSite, a separate SoftwareApplication for each application with its own id, URL, description and availability, plus ItemList, Product with price offers, BreadcrumbList and FAQPage. We kept FAQPage for extraction by LLMs, since Google no longer shows FAQ rich results as of May 2026.

The section with the four features of the endoscopy application, on the product page

Download buttons switch on when the file lands on the server

The /api/downloads route checks at runtime whether the installer exists in the server folder and returns its URL and size. There are three variants: Windows, macOS Apple Silicon and macOS Intel. Caddy serves them with accept-ranges, so downloads can resume. File names change in .env and apply at runtime, while the version shown on the card needs a redeploy. A product marked coming-soon stays locked even if the file exists.

It runs on a Hetzner VPS behind Caddy and pm2

The code lives in /home/deploy/gscopy, the pm2 process is called gscopy and listens on port 3100, and Caddy obtains the Let's Encrypt certificate automatically. The scripts/deploy.sh script does rsync, npm ci, build and a pm2 restart, then requests /ro from 127.0.0.1:3100 with curl.

The launch price is not shown as a struck-through price

The Omnibus Directive rules out fake discounts, so 1,000 EUR appears as a launch price with the standard price of 2,000 EUR beside it. The bundle costs 1,600 EUR against 2,199 EUR standard, and the "bought separately" reference (4,000 EUR) is calculated from the standard price, so it never goes stale. The footer carries ANPC and SAL. SOL/ODR is missing on purpose, because the EU platform was shut down on 20 July 2025.

The pricing page with the Both applications bundle and the launch price

The contact form is gone, the phone and email stayed

The first version, from 23 June 2026, had a contact API on Resend. The current version shows the phone and email with tel: and mailto: buttons, read from CONTACT in site.ts.

The source has 47 files in src and about 6,300 lines. The Git history has 11 commits, between 23 June and 13 July 2026.