WebView Architecture
Understanding How Your App Works
When you convert your HTML/CSS/JavaScript game or app into a native mobile app, it runs in a special architecture with three distinct layers. Understanding this architecture is crucial for properly configuring security and connectivity.
Web Architecture Analogy
Think of your mobile app like a traditional website:
- Flutter WebView = User's web browser (Chrome, Firefox, Safari)
- Internal Asset Server = CDN for static files (like Cloudflare, CloudFront, or Netlify)
- External Servers = Backend API, CDN, or asset servers (Express.js, Django, FastAPI, etc.)
Just like a website loads HTML/CSS/JS from a CDN and makes API calls to a separate backend, your mobile app loads your game/app assets from an internal server and can make API calls to your external servers.
Architecture Diagram
Your mobile app has three layers with different purposes:
The Three Layers Explained
Layer 1: Flutter WebView (The Browser)
What it is: A browser embedded in your mobile app that renders your HTML/CSS and runs your JavaScript.
What it does:
- Displays your game/app interface
- Executes your JavaScript code
- Enforces security policies (just like Chrome or Safari)
- Prevents unauthorized cross-origin requests
Important: The WebView acts exactly like a regular web browser. It enforces the same security restrictions (CORS, CSP) that Chrome or Firefox would enforce.
Layer 2: Internal Asset Server (The CDN)
What it is: A tiny web server running inside your mobile app that serves your files to the WebView.
What it does:
- Serves your HTML, JavaScript, CSS, images, and other assets
- Runs on a random port (e.g.,
http://localhost:49152orhttp://localhost:51234) - Only accessible from the device itself (not from the internet or local network)
- Configured via the SaaS dashboard with security headers
Important Facts:
- ⚡ Extremely fast - Files are loaded from the device, not the internet
- 🔒 Secure by default - Only accessible via localhost (127.0.0.1)
- 🎲 Random port - Port changes every time the app starts
- 🚫 No CORS needed - It only serves files, doesn't handle API requests
You configure: Content Security Policy (CSP) and other security headers via the SaaS dashboard.
👉 See Content Security Policy Guide for configuration details.
Layer 3: External Servers (Optional)
What it is: Your own backend server or external service that provides data, authentication, business logic, or assets (API, CDN, etc.).
What it does:
- Handles API requests from your game/app (GET, POST, PUT, DELETE)
- Serves assets like images, fonts, or libraries from CDNs
- Manages user data, game state, leaderboards, etc.
- Authenticates users and manages sessions
Important: If your game/app makes requests to external servers (API calls, loading assets from CDN, etc.), you must configure CORS on that server to allow requests from localhost with random ports.
You configure: CORS headers on your external server to allow cross-origin requests.
👉 See CORS Configuration Guide for setup instructions.
Key Distinctions
Common Scenarios
Scenario 1: Self-Contained Game (No External Server)
Your game is completely self-contained with no backend server.
You need to configure:
- ✅ CSP on the internal server (via SaaS dashboard)
- ❌ CORS - Not needed
Scenario 2: Game with External API or CDN
Your game calls an external API for leaderboards, user accounts, or game data, or loads assets from a CDN.
You need to configure:
- ✅ CSP on the internal server (via SaaS dashboard)
- ✅ CORS on your external servers (allow
localhost:*)
Scenario 3: Loading External Resources (CDNs)
Your app loads libraries or assets from external CDNs.
You need to configure:
- ✅ CSP to allow external CDNs (via SaaS dashboard)
- ❌ CORS - CDNs already configured correctly
Why the Random Port is Secure
You might wonder: "If the port is random and changes every time, how is this secure?"
The random port is a security feature, not a bug:
-
Localhost-only access: The internal server binds to
127.0.0.1, which means it's only accessible from the device itself, never from the network or internet. -
Port randomization prevents conflicts: Multiple apps can run simultaneously without port conflicts.
-
No port scanning attacks: Since the server isn't exposed to the network, attackers can't discover or connect to it.
-
CORS handles external servers: Your external servers validate the origin (any
localhost:*) to allow legitimate requests while blocking unauthorized origins.
Next Steps
Now that you understand the architecture, configure your app's security:
- Configure CSP for the internal server → Content Security Policy Guide
- Configure CORS for your API (if applicable) → CORS Configuration Guide
Quick Reference
Internal Asset Server (Configure via SaaS Dashboard):
- Purpose: Serve your app's files
- Headers: CSP, Cache-Control, Security headers
- See: Content Security Policy Guide
Your External Servers (Configure on your server):
- Purpose: Handle API requests and serve assets
- Headers: CORS headers (Access-Control-Allow-Origin)
- See: CORS Configuration Guide