CupsToGrams
CupsToGrams is een eigen tool-site die Amerikaanse cups omrekent naar grammen, per ingrediënt, op basis van echte dichtheid. We bouwden het merk, de interface, de rekenkern en de vindbaarheid zelf.
Bekijk live →
De uitdaging
Een cup meet volume, een gram meet gewicht. Er is dus geen omrekengetal dat voor alles klopt: een cup bloem weegt ongeveer 125 gram, een cup honing ongeveer 340 gram. Toch geven veel bestaande converters één vast antwoord, of verstoppen ze het antwoord achter advertenties en trage scripts terwijl iemand met bloem aan zijn handen staat te wachten.
Onze aanpak
We maakten het ingrediënt het uitgangspunt van de tool in plaats van een bijzaak. De 45 ingrediënten hebben ieder een eigen dichtheid, en de omrekeningen lopen via die waarde. Daaromheen bouwden we een eigen designsysteem in handgeschreven CSS, zonder framework, en een statische site die in de browser rekent.
Het resultaat
De site staat live op cupsngrams.com met 70 content-pagina's die vooraf worden gerenderd. Er is geen server-gerenderde route. De omrekening gebeurt in de browser, dus wat iemand in de converter intypt gaat niet naar een server. De uitbreidingen die sindsdien zijn gedaan, zoals de long-tail pagina's per hoeveelheid, komen uit echte Search Console-data en niet uit aannames.
Resultaat
45 ingrediënten, 70 content-pagina's, converter volledig client-side
Een vraag met een fout antwoord in omloop
Wie een Amerikaans recept naar de Europese keuken vertaalt, loopt vroeg of laat vast op één regel: "1 cup flour". De zoekopdracht die daarop volgt is voorspelbaar. Het antwoord dat mensen krijgen, klopt vaak niet. Een cup meet volume, een gram meet gewicht. Er is dus geen omrekengetal dat voor alles klopt. Toch geven veel converters precies dat: één vast getal, alsof bloem, honing en boter hetzelfde in de weegschaal leggen.
De cijfers laten zien hoe groot dat verschil is. Een cup all-purpose flour weegt ongeveer 125 gram, een cup granulated sugar ongeveer 200 gram, een cup boter 227 gram en een cup honing ongeveer 340 gram. Wie honing met het bloemgetal omrekent, zit er ruim 200 gram per cup naast, want honing weegt bijna drie keer zo veel als bloem. Dat is geen afrondingsverschil, dat is een mislukt recept.
We zagen daarnaast wat er verder mis is in deze niche. De zoeker staat in de keuken, heeft bloem aan zijn handen en wil binnen een seconde een getal. In plaats daarvan krijgt hij een advertentiemuur, een cookiedialoog en een script dat de layout laat verspringen op het moment dat hij wil tikken. De kans lag er dus niet in om nóg een converter te bouwen, maar om er een te bouwen die de eigenlijke vraag serieus neemt: welk ingrediënt zit er in die cup?
Het ingrediënt als kern van de tool
De inhoudelijke keuze die de hele site bepaalt, is dat het ingrediënt geen filter of extraatje is, maar de kern van de berekening. De 45 ingrediënten dragen ieder een eigen dichtheid, opgeslagen als gram per US cup en afgeleid naar gram per milliliter. De rekenkern reduceert een invoer eerst naar grammen en expandeert die daarna naar de gevraagde eenheid. Volume-eenheden lopen daarbij via de dichtheid van het gekozen ingrediënt, massa-eenheden gaan direct via hun gewichtsfactor. Een volume komt daardoor niet bij grammen uit zonder dat er een ingrediënt aan te pas is gekomen.
Daarmee dekt de tool zeven eenheden: cups, eetlepels, theelepels, milliliters, grammen, ounces en ponden, in willekeurige combinatie. De 45 ingrediënten zijn gegroepeerd in zes categorieën, van bloem en zetmeel tot suikers, zuivel en vetten, vloeistoffen, bakbenodigdheden en een restgroep met granen en noten. Een cup staat op de site vast op 240 milliliter, de waarde waar receptschrijvers doorgaans van uitgaan. Die waarde staat als één constante in de rekenkern, en de omrekeningen halen hem daar vandaan, dus de berekening zelf kan er niet naast zitten. De lopende teksten noemen dat getal daarnaast gewoon als tekst, en juist daar is het een keer misgegaan. Hoe dat is rechtgezet, staat verderop. Naast de converter zelf staat er een aparte pagina voor oventemperaturen, waar Fahrenheit, Celsius en gasstanden naast elkaar liggen.
We zijn ook expliciet over wat de cijfers wel en niet zijn. De dichtheden zijn zorgvuldige keukenbenaderingen uit gangbare bakreferenties, geen laboratoriummetingen, en dat staat zo op de site. Bij de ingrediëntpagina's staat daarom een meettip, want de manier waarop je bloem in een cup schept scheelt in de praktijk meer dan de derde decimaal van een dichtheid. Bloem aanstampen uit de zak levert 150 gram of meer op waar lepelen en afstrijken op 125 uitkomt. Dat eerlijk benoemen is nuttiger dan een precisie suggereren die niet bestaat.
Een warme keuken in plaats van een dashboard
De meeste rekentools zien eruit als een spreadsheet: koud, blauw, technisch. Dat past niet bij het moment waarop deze site gebruikt wordt. Iemand staat te bakken. We kozen daarom voor een warme keukenpalette: een crèmekleurige achtergrond met een zachte lichtgloed bovenin, terracotta als accent, olijfgroen en honinggeel als steunkleuren, en een diepe inktkleur voor tekst. De typografie zet dat door met Fraunces als serif voor de koppen, wat het geheel iets van een kookboek geeft, tegenover Nunito Sans voor de lopende tekst, die op een telefoon in een keuken leesbaar blijft.
Dit is een eigen designsysteem, geen template en geen CSS-framework. Er zit geen componentbibliotheek onder en geen utility-framework: de site draait op één handgeschreven stylesheet, en de runtime-afhankelijkheden zijn next, react en react-dom. Kleuren, radii, schaduwen en fonts staan als custom properties op de root, zodat een kleurbeslissing op één plek wordt genomen in plaats van door de bestanden heen verspreid te raken. Voor het delen van een link tekent next/og bij de build één OG-afbeelding in diezelfde keukenkleuren. Die afbeelding wordt buiten de stylesheet om gerenderd en kan de custom properties dus niet lezen, waardoor de palettewaarden daar apart staan. Dat is een plek die je bij een kleurwijziging bewust moet meenemen, en dat is precies waarom het in de code met een verwijzing naar de stylesheet is vastgelegd.
Toegankelijkheid hoorde bij het ontwerp en niet bij de oplevering. Er is een skip-link naar de hoofdinhoud, en de velden van de converter dragen een aria-label, want een los invoerveld naast een keuzelijst zegt zonder label niets. Focus is zichtbaar en in terracotta, of het nu om een veld van de converter gaat of om de zoekbalk boven het ingrediëntenoverzicht: het veld krijgt een terracotta rand met een zachte gloed eromheen. Het resultaatvak is een aria-live-regio, dus wie met een screenreader werkt hoort de nieuwe uitkomst zodra die verandert, zonder ergens naartoe te navigeren.
Statisch, client-side, zonder eigen backend
Technisch is CupsToGrams gebouwd op Next.js 16 met de App Router, React 19 en TypeScript in strict mode. De site wordt in zijn geheel vooraf gerenderd: een productiebuild levert 70 content-pagina's op, en geen daarvan is een server-gerenderde route. Dat zijn de homepage, vijf guide-pagina's, vijftien hoeveelheidpagina's, de 45 ingrediëntpagina's en vier info-pagina's. De ingrediëntpagina's en de hoeveelheidpagina's komen uit generateStaticParams, met dynamicParams uitgezet, zodat een onbekende slug netjes een 404 geeft in plaats van on-demand iets te renderen.
Er is geen eigen backend en geen database. De converter is rekenwerk in de browser en doet tijdens gebruik geen netwerkaanroep. Voor de bezoeker levert dat twee dingen op die je normaal tegen elkaar moet afwegen. Snelheid, omdat er niets te wachten valt op een server. En privacy, omdat er bij het omrekenen niets te versturen is: wat iemand in de converter intypt verlaat het apparaat niet. Dat is geen belofte in een privacyverklaring, het volgt uit de architectuur. De uitzondering is het contactformulier, dat een bericht naar een extern endpoint post, met een honeypot-veld erin zodat bots zichzelf verraden zonder dat een bezoeker een captcha voor zijn kiezen krijgt. Die uitzondering staat los van de tool, en het onderscheid tussen de twee is wat de privacytekst benoemt.
Een detail waar we bewust moeite in hebben gestoken, is de scheiding tussen de data die de browser nodig heeft en de data die alleen de pagina nodig heeft. De teksten per ingrediënt, dus de intro, de meettip en de drie FAQ's, staan in een module die door Server Components wordt geïmporteerd. De interactieve converter importeert een aparte, lean module met alleen slug, naam, categorie en dichtheid. Die prose komt daardoor wel in de HTML terecht, waar Google hem leest, maar blijft buiten de JavaScript-bundle die de bezoeker moet downloaden. Er staan vandaag ook geen advertenties op de site: de advertentie- en consent-componenten renderen niets tenzij een environment-variabele expliciet aan staat, en het gereserveerde blok heeft een vaste hoogte, zodat de layout niet gaat verspringen als dat ooit verandert.
Vindbaarheid die uit de data komt, niet uit een aanname
De pagina's dragen eigen metadata met een eigen canonical, JSON-LD via één gedeelde graph-functie, een plek in de sitemap en de gedeelde OG-afbeelding. De sitemap wordt afgeleid uit dezelfde databestanden als de pagina's zelf: de ingrediënt-slugs en de hoeveelheid-slugs komen uit dezelfde lijsten die de routes genereren. Een ingrediënt toevoegen in de data is daardoor genoeg om de route, de pagina en de sitemap-entry te laten bestaan, zonder dat iemand daarnaast nog een lijst moet bijwerken die vergeten kan worden.
Interessanter is waar we nee tegen hebben gezegd. De JSON-LD emitteert bewust geen WebApplication-node, omdat Google's rich result daarvoor een aggregateRating of review vereist. Wij verzinnen geen beoordelingen, dus zo'n node zou niet in aanmerking komen en alleen validatiefouten opleveren. Om dezelfde reden staat er geen SearchAction in: er is geen server-side zoekendpoint, dus die claim zou niet waar zijn. En de sitemap draagt een handmatig beheerde datum in plaats van de buildtijd, want bij elke deploy alle URL's opnieuw als "gewijzigd" stempelen is geen echt versheidssignaal, alleen verspild crawl-budget.
De vijftien pagina's onder /cups-to-grams zijn rechtstreeks uit Search Console-data ontstaan. De grootste zoekcluster bleek ingrediënt-agnostisch te zijn: "1/2 cup in grams", "3/4 cup in grams", "2 cups to grams". Die vragen hadden geen natuurlijk doel tussen de ingrediëntpagina's, die juist "1 cup bloem in grammen" beantwoorden, en kwamen op de homepage terecht, ver weg in de resultaten. Elke hoeveelheidpagina beantwoordt nu één hoeveelheid voor de hele ingrediëntenlijst in één tabel, met eigen handgeschreven tekst per pagina, zodat het geen bijna-duplicaten van elkaar worden. Even belangrijk is wat we niet hebben gebouwd: decimalen zonder aantoonbare vraag kregen geen eigen pagina, want een pagina per decimaal is een doorway-patroon. De decimale vorm is in plaats daarvan opgenomen in de bestaande breukpagina's, en waar een decimaal een afronding is, zoals 0,33 voor een derde, zegt de tekst "about", omdat het anders onjuist zou zijn.
Waar het nu staat
De eerste commit dateert van 3 juli 2026. Sindsdien is de site niet stil blijven staan: verificatie in Search Console, een eigen 404 die doorverwijst naar de populairste ingrediënten in plaats van naar een doodlopende straat, contrastcorrecties, de omgekeerde zoekrichtingen als eigen pagina's, de long-tail uitbreiding, en het rechtzetten van een tegenstrijdigheid tussen 237 en 240 milliliter die in de teksten was geslopen. Dat laatste is typerend voor hoe we deze sites onderhouden. De rekenkern gebruikte 240, maar een FAQ-antwoord noemde 237, de striktere customary definitie van een US cup. Die pagina's leggen nu allebei de getallen naast elkaar en zeggen welke de site aanhoudt, en waarom dat verschil van drie milliliter in het niet valt bij hoe verschillend een ingrediënt zich laat aandrukken. Een converter die twee verschillende waarden voor een cup noemt, ondermijnt precies het enige dat hij verkoopt: dat het getal klopt.
Voor snellere indexering meldt een eigen script na een deploy de sitemap-URL's bij IndexNow, en er ligt een llms.txt met een korte uitleg van wat de site doet en hoe hij rekent, voor de generatieve zoekmachines die inmiddels ook langskomen. De keyword-strategie per route staat vastgelegd in de repo, samen met de guardrails: één canonical per pagina, titels onder de 60 tekens inclusief de merk-suffix, en geen em-dashes in de Engelse copy. Een volgende uitbreiding begint daardoor bij wat er al besloten is, niet bij een leeg blad.
Wat CupsToGrams laat zien, is dat FusionStudios dit soort werk in zijn geheel zelf doet. De positionering in de niche, het merk en het designsysteem, de rekenkern in TypeScript, de statische architectuur en de vindbaarheid komen uit één hand en uit één repository. We bouwen deze sites niet als portfoliostuk om ze daarna te laten liggen. Ze staan live, ze worden op echte data bijgestuurd, en de keuzes die we erin maken zijn dezelfde keuzes die we in opdracht zouden maken.
Klaar om jouw merk te laten groeien?
Vertel ons over je project. We denken graag met je mee, vrijblijvend.
Vrijblijvend. Je hoort binnen één werkdag van Jamey.