Skip to content
andriiemail
2026Live

Devotament

Rebuilt a furniture company's brochure site into a self-serve platform with its own admin, local SEO, and Cloudinary-backed media.

The owner ships new projects without a developer.

Role
Solo — frontend, backend, admin panel, deploy
Timeline
1 month
Stack
Next.jsTypeScriptFirebaseCloudinaryVercel

The business problem

Devotament is a Romanian company that builds custom furniture. They already had a website, but it was a brochure nobody could touch without a developer: adding a new portfolio project or fixing a line of copy meant calling a programmer. Local search barely surfaced them. Customer reviews lived in Google and were never pulled onto the site. And there wasn't a single request form — the site showed the work beautifully but brought in no leads.

The constraints

  • One month, solo. One person across frontend, backend, admin panel, and deploy.
  • Design was handed to me — the visual comp existed; several component-behavior decisions were mine (the client signed off and was happy).
  • Budget on a per-page rate (€70–150/page depending on complexity) — no room for heavy infrastructure or long build cycles.
  • The client had to run the site themselves afterward, without me.

What I built and why

A static Next.js site on Vercel, plus a thin custom admin panel the company uses to manage its own portfolio and reviews. Everything a visitor sees is rendered on the server — only finished data reaches the browser; server code and keys never ship in the bundle. Media goes through Cloudinary, wired to the database. I chose Firebase on purpose: the data model is simple, and neither realtime nor complex relational queries were needed — a right-sized store beats a heavier one I'd have to maintain.

A product decision inside the build: reviews are split into two kinds — tied to a specific project, and global. This comes from real behavior: some clients leave a review about the company as a whole, not about one project — there's nothing to attach it to. That review lands in Global Review and appears in the general blocks instead of being lost.

What I deliberately rejected: a headless CMS (Sanity/Strapi). That's an extra layer and a subscription for what amounts to three entities — projects, reviews, pages. A thin admin panel shaped to their data model was cheaper to maintain and didn't lock the client into someone else's pricing tier.

Technical decisions, with the cost of each

Decision 1 — Cloudinary wired to the DB, instead of Google Cloud Storage or a hand-rolled pipeline.

Cloudinary gave me image optimization and transforms out of the box (formats and sizes for next/image) with no pipeline of my own, and I tied each file's lifecycle to its database record — delete a project in the admin, and its images are deleted in Cloudinary too. No orphaned files, no quietly growing storage bill.

The cost: an external dependency and free-tier limits. If traffic and the media library grow, I'll have to watch the quota or pay. Negligible at current volume, but it's debt I took on knowingly.

Decision 2 — a hard server/client boundary, instead of "just pull the logic into the client because it's easier."

Server code never mixes with client code: data and secrets stay on the server, only serialized props cross into client components, and data access goes through closed APIs. Admin auth is a JWT plus a server-side key in env — match, and you're in. Internal logic and stray data physically never reach the browser bundle.

The cost: more boundary code — I have to be deliberate about what's server versus client and pass state through props instead of reaching for data inside a component. Slower to write, but safer and easier to keep in my head.

The result — honestly

  • Lighthouse SEO — 100. Strong on the other axes too; exact numbers after a clean run.
  • Traffic — ~70 visits/day and climbing. Live for ~2–3 weeks, so these are early figures.
  • Feels fast, but I did not measure before/after LCP or TTFB — there's no "before" baseline; I never benchmarked the old site. Straight answer.
  • The client is happy and runs the platform themselves — which was the goal.
Back to workUpdated June 22, 2026