Een companion-webapp is het browseroppervlak van een product dat vooral in een mobiele app leeft: de plek waar een klant zich aanmeldt vóór het installeren, waar een gedeelde link opent voor iemand zonder de app, waar werk dat op een telefoon begon op een desktop verdergaat. Het is hetzelfde product, op dezelfde API, gevormd naar waar een browser werkelijk goed in is — in plaats van een port van de app of een brochure erover.
De meeste bureaus bouwen de ene of de andere kant. Wij leveren Flutter-apps, webfront-ends en de backendservices die beide gebruiken — en dat verandert de engineering, want de vraag "op welk oppervlak hoort deze functie thuis" wordt beantwoord door één team dat naar één systeem kijkt, niet uitonderhandeld tussen twee leveranciers.
De producten die we bouwen
- Klantwebapps naast mobiele apps — het volledige product in de browser waar dat zinvol is, of de bewuste deelverzameling waar dat niet zo is
- Publieke, deelbare oppervlakken — de pagina's waarop een gedeelde link uitkomt, gerenderd en indexeerbaar, die overdragen aan de app wanneer die is geïnstalleerd
- Realtime webclients — live data in de browser uit dezelfde feed die de apps gebruiken
- Backoffices voor hetzelfde product — de kant voor operators is een eigen discipline, behandeld op beheerpanelen en dashboards
- De webkant gebouwd op Nuxt — moet het companionoppervlak scoren, dan is de machinerie onze praktijk voor Nuxt-ontwikkeling
Wie je companion-webapp bouwt
Twee producten in productie laten het patroon zien, elk met een app en een weboppervlak op één backend.
Formtastic — één platform, drie clients
Formtastic draait als een Nuxt-webapplicatie plus Flutter-apps voor iOS, iPad en Android, allemaal tegen dezelfde backend in Django en Go. Het leerzame is hoe functies per oppervlak anders landen: spraak naar tekst neemt op het web audio op in de browser en stuurt die naar een transcriptie-endpoint, omdat er al een backend was om uit te breiden — terwijl de mobiele apps Whisper op het toestel meebundelen, omdat bouwplaatsen geen bereik hebben. Dezelfde functie, twee implementaties, elk eerlijk over zijn oppervlak. Dat oordeel, meer nog dan frameworkvaardigheid, is wat een product met twee oppervlakken werkelijk vraagt.
ExtraETF — één realtime feed, elke client
Voor ExtraETF bouwden we de WebSocket-service in Go die live marktdata uitzendt naar zowel web- als mobiele clients — duizenden gelijktijdige verbindingen, updates samengevoegd tot het tempo dat een mens die naar een koers kijkt werkelijk nodig heeft. Wij bouwden de mobiele apps en de realtimelaag; de webclient die haar consumeert is van het eigen team van de klant. Een goed ontworpen service voedt ook oppervlakken die je zelf nooit bouwt.
Wat een product met twee oppervlakken werkelijk vraagt
Vier disciplines voorkomen dat een app en een weboppervlak uiteendrijven tot twee producten.
Eén API die beide eerlijk bedient
Op het moment dat het web "gewoon één speciaal endpoint" nodig heeft, heb je twee backends onder één naam. We ontwerpen de API als het enige contract van het product — dezelfde authenticatie, dezelfde modellen, dezelfde versionering voor elke client — en waar de oppervlakken oprecht verschillende vormen van data nodig hebben, staat dat verschil in het contract zelf, in plaats van weggemoffeld in een client.
Bepalen wat de webversie is
De dure fout is "de app, maar dan in een browser". Een companionoppervlak verdient zijn budget door te doen wat de app niet kan: bereikbaar zijn vanuit een zoekresultaat, direct openen vanuit een gedeelde link, een toetsenbord en een groot scherm bieden voor zwaar bewerkwerk. We scopen het weboppervlak functie voor functie tegen die toets — en een functie uit de webversie schrappen is een besluit dat we hardop verdedigen, geen gat dat later wordt ontdekt.
De overdracht tussen web en app
Een gedeelde link hoort de app te openen wanneer die is geïnstalleerd, de webpagina wanneer niet, en nooit een kapot tussenscherm. Universal links op iOS en app links op Android, de terugvalpagina's erachter, en de aanmeldstroom die in een browser begint en in de app verdergaat — deze naad is waar producten met twee oppervlakken het zichtbaarst gebruikers lekken, dus engineeren we hem bewust in plaats van aan te nemen dat hij werkt.
Rendering afgestemd op de taak van de pagina
De publieke, deelbare pagina's renderen op de server zodat crawlers en linkvoorbeelden echte content zien; de ingelogde werkruimte erachter rendert als de applicatie die ze is. De afwegingen staan uitgewerkt op de pijler webontwikkeling, en de keuze is per route, niet per project.
Hoe we werken
Bouw met vaste scope. Wij nemen het weboppervlak van functiescoping tot uitrol, tegen je bestaande API of een die we ernaast bouwen.
Teamuitbreiding. Onze engineers sluiten aan bij het team dat het product bezit — zie teamuitbreiding. Moet de mobiele kant ook gebouwd worden, dan is dat onze Flutter-praktijk.
Hoe dan ook sturen we, zodra we de eisen scherp hebben, binnen twee werkdagen een offerte met duidelijke scope.
Wat een companion-webapp kost
Een companionoppervlak wordt geprijsd vanuit dezelfde gepubliceerde niveaus als de pagina webontwikkeling: een geauthenticeerde webapp op je bestaande API valt in het webappniveau op € 12.000-32.000, terwijl een volwaardig tweede oppervlak met realtimefuncties, betalingen of een multi-tenant-structuur als werk op SaaS-niveau wordt geprijsd vanaf vanaf € 40.000.
Dit zijn dezelfde sleutels die de prijstabel van de pijler renderen, dus de twee kunnen niet uiteenlopen. Wat het bedrag beweegt: hoeveel van de API al bestaat en hoe zuiver hij voor meer dan één client is ontworpen, hoeveel van het product de webversie dekt, en of realtimefuncties op een bestaande feed meerijden of er een gebouwd moet worden.
Veelgestelde vragen
Veelgestelde vragen van teams wier product in een app leeft en waar steeds vaker om een browserversie wordt gevraagd.
Bekijk beide oppervlakken in de casestudy over Formtastic, lees hoe de realtime feed van ExtraETF naar elke client uitwaaiert, of begin bij de pijler webontwikkeling.
