Demo project
3D printing store: PrintCraft
A catalog with color variants, a custom print page, a cart.
development · Next.js 15 · TypeScript · Tailwind · Zustand

The task
PrintCraft is a 3D printing workshop: it prints household items, desk accessories and kids’ things on Bambu Lab machines in PLA and PETG, and takes custom jobs from customers’ own models. Such a business needs a real store, not a social media page: a catalog with plastic color options, a cart, checkout, and a separate page for “print from my model” requests. The tricky product is a personalized lithophane night light: without a field for the child’s name, the workshop simply would not know what to print. A demo project: the company is fictional, the brief is real.
The solution
Tactile minimalism with a Scandinavian-shop feel: a warm light background, the object as the hero, product photos on plain color mats, one terracotta accent. Cards have no borders or shadows - attention goes to the things, not the interface. Technically it is Next.js 15 with static export: the output is plain HTML pages that host anywhere and need no server.
- The catalog filters by three categories on the client, without reloads; a counter shows how many items are visible.
- Plastic color swatches sit right in the product card. The chosen color is part of the cart line key: one planter in mint and one in terracotta are two lines, not one line with quantity 2.
- The night light is a personalized product: a required name field up to 12 characters. The value is stored in the cart line and repeated at checkout, so the buyer verifies it before printing starts.
- The cart is Zustand with persist in localStorage - it survives a closed tab. The header counter renders only after mount, otherwise the static HTML and the client would diverge on hydration.
- The custom print page walks through three steps - a model or an idea, a quote within a day, printing in 3-5 days - and ends with a request form.
- Infographics are inline SVG components: product dimension schemes, a PLA vs PETG comparison, a delivery timeline. Every big number on the page is explained visually.
Details that are easy to miss
- The checkout phone mask follows the browser language: a +7 format for Russian-speaking visitors, +1 for everyone else. The locale is read after mount to keep the static export hydration clean.
- The engraving field reports errors honestly: aria-invalid when it fails, hints linked via aria-describedby, and a warning that the name cannot be changed once printing has started.
- The page keeps its promises consistent: the “hooks hold up to 5 kg” claim reads the same in the product card and in the FAQ. The FAQ also spells out the return policy - and states that the personalized night light is non-returnable as a custom-made item.
- Demo hygiene: a disclaimer page says the workshop does not exist; noindex sits in the metadata and in a _headers file with X-Robots-Tag, so the export never competes with real stores in search.
- Consent to data processing is a required checkbox with a link to a separate policy page, in both forms.
- prefers-reduced-motion cuts animations, transitions and smooth scrolling down to 0.01 ms.
The numbers
Everything is counted from the sources and the static export: 17 pages, 9 products across three categories, 5 plastic colors. The cart and the forms live on the client, so the store deploys as a set of static files - no server, no server costs.
Screenshots




