Naar de inhoud
fusionstudios.
Online conversietools2026Eigen project

ImageConvert

ImageConvert (imageconvert.tools) is een van de organische tool-sites die we volledig zelf hebben gebouwd: merk, ontwerp, techniek en vindbaarheid. Het is een beeldconverter en gereedschapskist die in de browser van de bezoeker draait, zonder eigen backend en zonder database, en waarbij het bestand dat je omzet het apparaat niet verlaat.

Bekijk live →
ImageConvert, online conversietools website ontworpen door Fusionstudios

De uitdaging

De niche rond "afbeelding converteren" is groot, maar het bestaande aanbod is grotendeels slecht. Bestanden gaan naar een server, resultaten zitten achter wachtrijen, limieten of watermerken, en de pagina's die de zoekopdracht opvangen zeggen niet wat er met je pixels gebeurt. De tweede opgave was schaal zonder rommel: elk formaatpaar wil een eigen pagina, en dat leidt in deze niche bijna altijd tot tientallen vrijwel identieke teksten met alleen twee formaatnamen verwisseld.

Onze aanpak

We hebben één databestand tot bron van waarheid gemaakt, waaruit de 12 formaten, de 91 conversieparen en de per-formaat content voortkomen, en daarnaast een eigen design-systeem in platte CSS gebouwd zonder framework of template. De conversie draait grotendeels op de Canvas API, aangevuld met eigen encoders voor BMP en ICO, libavif in WebAssembly voor AVIF, en losse decoders voor HEIC en TIFF, terwijl video en audio via FFmpeg in WebAssembly lopen die we same-origin meeleveren. Voor vindbaarheid kozen we bewust: alle 91 routes bestaan en werken, maar alleen de 30 pagina's die er recht op hebben staan in de index en in de sitemap, namelijk 16 conversies met echt zoekvolume en 14 met handgeschreven inhoud.

Het resultaat

De site bestaat uit 115 statisch gegenereerde pagina's: 91 conversieparen, 12 tools, 5 gidsen en 7 vaste pagina's, gebouwd op Next.js 16 met React 19 en TypeScript in strict mode. Het project heeft geen eigen API-route, geen server action en geen database, en het converteren zelf gebeurt op het apparaat van de bezoeker. De privacybelofte is daarmee geen tekst in een voetnoot maar een eigenschap van de architectuur: er is geen upload-pad waarlangs de afbeelding ons zou kunnen bereiken.

Resultaat

12 formaten, 91 conversieroutes, 115 statische pagina's

Waarom juist deze niche

Iemand met een HEIC-foto van zijn iPhone die nergens geüpload kan worden, of een WebP die het ontwerpprogramma niet opent, typt een heel letterlijke zoekopdracht in. Het antwoord dat hij vindt is meestal een site die zijn bestand naar een server stuurt, hem laat wachten in een wachtrij, een limiet oplegt op het aantal bestanden per uur, of een watermerk achterlaat. Het onderliggende model is dat het bestand het product is: het wordt verwerkt op andermans machine en de bezoeker heeft geen idee wat daar daarna mee gebeurt.

Wat ons opviel is dat de technische noodzaak voor dat model grotendeels weg is. De browser kan de formaten waar het in de praktijk om draait zelf decoderen en encoderen. De upload bestaat vaak niet omdat het moet, maar omdat het bedrijfsmodel eromheen is gebouwd. Dat maakte de niche interessant: er is een concrete, veelgezochte behoefte en een aanbod dat structureel slechter is dan wat technisch mogelijk is.

De tweede observatie ging over de teksten. De pagina's die deze zoekopdrachten opvangen leggen zelden uit wat er met de afbeelding gebeurt. Dat een animatie verdwijnt, dat een transparante achtergrond wit wordt, dat een icoon wordt verkleind naar 256 pixels: precies de dingen waar mensen achteraf op stuklopen, staan er nauwelijks. Daar hebben we onze inhoud op gebouwd.

Het ontwerp: een eigen systeem, geen framework

ImageConvert heeft geen CSS-framework en geen template. Het hele visuele systeem staat in één eigen stylesheet met custom properties als basis: een set tokens voor kleur, lijn, schaduw en radius, en daaronder een tweede set die voor het donkere thema de kleuren en de schaduwen opnieuw zet. De geometrie blijft daarbij bewust ongemoeid. De radius van een kaart of een knop is in beide thema's dezelfde, want de vorm van een element is niet iets wat een thema hoort te veranderen; alleen wat licht en donker écht onderscheidt, wordt herschreven. Dat is een keuze en geen puritanisme: een gereedschapsite bestaat uit een klein aantal terugkerende onderdelen (een dropzone, een knop, een tabel, een kaart) en die zijn met eigen CSS sneller en lichter dan met een framework dat voor een heel andere schaal is ontworpen.

De visuele taal is rustig en licht van opzet: een blauwe merkkleur, een zachte radiale gradiënt achter de kop, veel wit, en de Geist-familie voor tekst en cijfers. Dat past bij het onderwerp. Iemand die hier komt, wil geen ervaring, hij wil een bestand. Het merk moet betrouwbaar overkomen en dan uit de weg gaan. De blauwe accentkleur is daarom gerantsoeneerd tot wat met kleur iets moet zéggen: het logo, de actieknop, de focusrand, een link, een geselecteerd stuk tekst, de rand van de dropzone op het moment dat je er een bestand boven houdt. Wat puur versiering zou zijn, krijgt geen accent.

Twee details verraden waar de aandacht zat. Het thema wordt gezet door een klein script dat vóór het renderen draait en uit localStorage of de systeemvoorkeur leest, zodat een donker thema niet begint met een witte flits. En de blur op de plakkende header staat alleen op bredere schermen aan, met een dekkende variant daaronder, omdat dat effect zwaar is voor de compositor tijdens het scrollen op een telefoon. Dat is het soort afweging waar je een eigen systeem voor nodig hebt, omdat een template die keuze al voor je heeft gemaakt.

De techniek: alles gebeurt op het apparaat zelf

De site draait op Next.js 16 met de App Router, React 19 en TypeScript in strict mode. Er is geen eigen backend en geen database: het project bevat geen API-route en geen server action. De pagina's worden bij de build statisch gegenereerd, dus wat de bezoeker aan de kant van de server aantreft, is al af voordat hij aanklikt. Tijdens het converteren zelf gaat de afbeelding het netwerk niet op, om de eenvoudige reden dat er geen code is die haar verstuurt. De uitzonderingen op die stilte zijn eerlijk te benoemen en raken het bestand niet: het contactformulier stuurt een bericht naar een extern eindpunt, en de zwaardere wasm-modules worden bij het eerste gebruik van ons eigen domein opgehaald.

De conversie zelf loopt via de Canvas API van de browser, aangevuld waar die tekortschiet. HEIC van Apple wordt gedecodeerd met een wasm-decoder, TIFF met een pure JavaScript-decoder, en SVG wordt eerst voorzien van expliciete afmetingen (uit de viewBox als die ontbreken) voordat het naar pixels wordt gerasterd. Aan de uitvoerkant hebben we de encoders geschreven die de browser niet biedt: een 24-bit BMP met bottom-up rijen zoals oude Windows-software die verwacht, geschreven in blokken van 64 rijen met een adempauze ertussen zodat de tab niet vastloopt op een grote afbeelding, en een ICO waarin het beeld als 32-bit PNG wordt verpakt en tot maximaal 256 bij 256 wordt geschaald. GIF, TIFF en PDF gaan via gespecialiseerde bibliotheken, en een batch wordt zonder hercompressie tot één zip gebundeld.

Video en audio zijn een geval apart: die lopen op FFmpeg gecompileerd naar WebAssembly, en die core leveren we same-origin mee vanuit de eigen public-map in plaats van via een CDN van derden. De engine is ruim 30 MB en wordt na de eerste keer gecached, wat we op de pagina zelf ook gewoon zo opschrijven. Het praktische gevolg van al deze keuzes is dat er geen limiet is, geen wachtrij en geen account, en dat het bestand het apparaat niet verlaat. Niet omdat wij dat beloven, maar omdat de converter geen upload-pad heeft waarlangs het bestand ergens anders terecht zou kunnen komen.

Eerlijk zijn over wat de converter doet

Bij elk handgeschreven conversiepaar hoort een apart veld dat beschrijft wat de encoder werkelijk met de pixels doet. Dat een animatie verloren gaat en alleen het eerste frame overblijft. Dat een transparante achtergrond bij een BMP op wit wordt platgeslagen omdat 24-bit geen alfakanaal heeft. Dat een TIFF de kwaliteit niet terugbrengt die een lossy AVIF al had weggegooid, maar alleen verder verlies stopt. De regel bij dat veld staat in de code zelf: de tekst wordt tegen de implementatie gecontroleerd en niet andersom, want een belofte die niet klopt is erger dan geen belofte.

Het scherpst kwam dat naar voren bij het exporteren naar AVIF. De voor de hand liggende weg, de browser om een AVIF vragen via canvas.toBlob, bleek onbruikbaar: de HTML-standaard verplicht een browser alleen tot PNG, en Chrome beantwoordt een verzoek om image/avif doodgemoedereerd met een blob van het type image/png. Een PNG met een AVIF-naam erop, en de bezoeker komt daar pas veel later achter. Daarom laten we AVIF niet aan de browser over maar encoderen we het met libavif, gecompileerd naar WebAssembly. Die encoder is ongeveer 3,4 MB, staat same-origin in onze eigen public-map en wordt pas opgehaald bij de eerste AVIF-conversie in plaats van bij het laden van de pagina, zodat wie nooit naar AVIF exporteert er ook niets voor betaalt. Een mislukte laadpoging onthouden we niet, want anders zou één haperend moment de AVIF-export voor de rest van de sessie slopen.

De controle achteraf is om dezelfde reden omgedraaid. Het MIME-label is precies het ding dat hier eerder loog, dus dat vertrouwen we niet: we lezen de bytes zelf. Een echte AVIF begint met een ftyp-box waarvan het merk avif of avis is, en alleen als dat klopt gaat het bestand naar de bezoeker. Komt er niets terug, of komen er bytes terug die geen AVIF zijn, dan faalt de conversie hard met een leesbare melding die zegt wat er aan de hand is en wat wel werkt, in plaats van iets af te leveren onder een verkeerde naam. Van de tien pagina's die naar AVIF exporteren staan er drie in de index: jpg, png en webp naar AVIF, de drie waar de vraag aantoonbaar zit en waar de encoder-tekst met de hand is geschreven. De andere zeven werken precies zo goed, maar blijven buiten de index tot ze eigen inhoud hebben. Dat een conversie werkt is hier de toegangsprijs, niet het argument.

Vindbaarheid: 91 routes, 30 in de index

De programmatische kant is simpel te beschrijven: één databestand met 12 formaten levert 91 geldige conversieroutes op, en die worden allemaal statisch gegenereerd. Samen met 12 tools, 5 gidsen en 7 vaste pagina's komt de site uit op 115 statische pagina's. Dat is het soort schaal waarop tool-sites de fout in gaan: ze zetten alle varianten in de sitemap en laten Google uitzoeken welke ertoe doet.

Wij hebben het omgekeerd aangepakt. Een pagina komt in de index als hij er recht op heeft: ofwel omdat het een conversie met echt zoekvolume is (16 paren, geselecteerd op keyword research), ofwel omdat er handgeschreven, pagina-specifieke tekst op staat (14 paren, geen overlap met de eerste groep). Dat zijn er samen 30. De overige 61 routes blijven gewoon bestaan en werken, de converter doet het daar precies zo goed, maar ze staan op noindex met follow: ze concurreren niet om indexruimte met sjabloontekst en geven hun linkwaarde nog steeds door. Wat er in de sitemap komt en wat een pagina in haar eigen metadata over indexering zegt, lezen daarvoor dezelfde functie, zodat die twee niet uit elkaar kunnen lopen. Robots.txt doet daar niets aan en hoort dat ook niet te doen: die zet de deur open en wijst naar de sitemap, het sturen gebeurt per pagina.

De pagina's met handgeschreven tekst openen met een eigen alinea onder de H1 in plaats van met dezelfde zin waarin twee formaatnamen zijn ingevuld, en hun eigen vragen staan vooraan in de FAQ en in de gestructureerde data. Daarnaast staan er vijf uitgebreide gidsen (WebP vs PNG, JPG vs PNG, HEIC vs JPG, AVIF vs WebP en een uitleg over hoe compressie werkt) die heen en weer linken met de converters en tools waar ze bij horen. De rest van de vindbaarheid is degelijk handwerk: per pagina een canonical, JSON-LD met FAQPage, BreadcrumbList en WebApplication, OG-beelden via next/og, permanente redirects van de jpeg-variant naar de canonieke jpg-URL's, een llms.txt voor taalmodellen, en een IndexNow-script dat de sitemap na een deploy aanmeldt. Een klein maar tekenend detail: de lastModified in de sitemap komt uit een handmatig bijgewerkte constante en niet uit new Date(), want anders meldt elke deploy vals dat de hele site is veranderd.

Waar het nu staat en wat het laat zien

De site is live op imageconvert.tools en draait sinds begin juli 2026. Hij is compleet in de zin dat wat er staat werkt: 12 formaten, 91 conversieroutes, 12 losse tools van compressor en resizer tot QR-generator, en video- en audioconversie naar zes formaten, zonder dat er een bestand wordt verstuurd. De advertentieschakelaar staat standaard uit en zit achter een omgevingsvariabele, zodat we die keuze kunnen maken wanneer we hem willen maken en niet omdat de code hem al heeft afgedwongen. De inhoudelijke laag is het jongst: de handgeschreven conversieparen zijn het werk van de afgelopen weken en rollen we stap voor stap uit, wat betekent dat de 30 de regel in de codebase is en de index daar nog naartoe groeit.

Voor ons is dit geen zijproject maar een proefstuk dat we in de lucht houden. We schrijven de merknaam, het ontwerp, de encoders, de teksten en de technische SEO zelf, in één repository, en we onderhouden ze allemaal. Dat betekent ook dat we de gevolgen van onze eigen keuzes dragen: de eerlijke tekst over wat een GIF-conversie kost, de pagina's die we bewust uit de index houden, de blur die op mobiel uit staat, en de 3,4 MB aan encoder die we liever zelf meeleveren dan dat we de browser op zijn woord geloven.

Wat het voor een opdrachtgever laat zien is eenvoudig genoeg. Als wij een site bouwen, is dat niet een template met een logo erop en een SEO-plugin erachter. Het is een eigen ontwerpsysteem, een architectuur die past bij wat het ding moet doen, en een vindbaarheidsstrategie waarin ook nee zeggen een keuze is. ImageConvert is de plek waar we dat op onszelf hebben toegepast, met de beperkingen zichtbaar in plaats van weggeschreven.

Volgende caseHueKit

Klaar om jouw merk te laten groeien?

Vertel ons over je project. We denken graag met je mee, vrijblijvend.

5.0 op Google · 8 reviewsLive binnen 5 weken
Start een project

Vrijblijvend. Je hoort binnen één werkdag van Jamey.

Liever eerst even sparren? App of bel Jamey op 06 40866279.

BellenWhatsAppStart een project