Publishing a Unity WebGL Game to the Browser
The publishing decision starts with a fundamental choice: self-host on your own domain, publish through game portals, or do both. Self-hosting gives you full control over the player experience, analytics, monetization, and SEO. Game portals provide built-in audiences but impose their own rules, SDK requirements, and revenue splits. Many successful web game developers use portals for discovery and their own site for the premium experience.
Step 1: Prepare the Production Build
Before deploying, create a release-quality build with every optimization applied. In Build Settings, disable "Development Build" and "Autoconnect Profiler" to remove debugging overhead. In Player Settings, set Compression Format to Brotli for the smallest download size. Enable "Data Caching" so returning players skip re-downloading unchanged assets. Set Managed Stripping Level to High and enable Strip Engine Code.
Create a custom HTML template if you have not already. The default template is functional but generic. A custom template lets you match the hosting page's branding, implement a custom loading screen with your game's artwork, handle error states gracefully (showing a "your browser does not support WebGL" message instead of a blank page), and add mobile viewport meta tags for responsive sizing. Store the template in Assets/WebGLTemplates/YourTemplateName/ and select it in Player Settings.
Test the production build locally before deploying. Use a local web server (Python, Node.js, or any static file server) rather than Unity's "Build And Run" to simulate real hosting conditions. Verify that compression works by checking response headers in the browser's Network tab. Confirm that the game loads, plays, and saves correctly in Chrome, Firefox, Safari, and Edge.
Step 2: Configure Web Server MIME Types and Headers
Incorrect server configuration is the most common cause of deployment failures. WebGL builds require specific MIME types and, when using compression, specific content encoding headers.
The essential MIME type configuration ensures .wasm files are served as application/wasm. Without this, some browsers refuse to compile the WebAssembly module, and performance is degraded on others because the browser falls back to slower compilation paths. For Brotli-compressed builds, the .wasm.br file should be served with Content-Type: application/wasm and Content-Encoding: br. Similarly, .js.br files need Content-Type: application/javascript with Content-Encoding: br, and .data.br files need Content-Type: application/octet-stream with Content-Encoding: br.
For Nginx, add these directives inside the appropriate location block. For Apache, use AddType and AddEncoding directives in .htaccess. For cloud hosting (AWS S3, Google Cloud Storage, Azure Blob), set metadata on each uploaded file with the correct Content-Type and Content-Encoding values. Many deployment issues trace back to the hosting platform stripping or overriding these headers.
CORS (Cross-Origin Resource Sharing) headers are needed if the game loads assets from a different domain than the one serving the HTML page. This is common when using a CDN for asset delivery. Add Access-Control-Allow-Origin: * to asset responses, or restrict it to your specific domain for better security.
If your game uses SharedArrayBuffer for threading support, you need COOP and COEP headers: Cross-Origin-Opener-Policy: same-origin and Cross-Origin-Embedder-Policy: require-corp. These headers enable high-resolution timers and SharedArrayBuffer but restrict how the page can interact with cross-origin resources, so test thoroughly after enabling them.
Step 3: Set Up a CDN for Fast Global Delivery
A Content Delivery Network caches your game files at edge locations around the world, reducing load times for players far from your origin server. For a WebGL game where the initial download can be 10-30 MB, the difference between serving from a single origin versus a CDN edge node can be several seconds of load time.
Popular CDN options include CloudFront (AWS), Cloudflare, Fastly, and Bunny CDN. Each handles WebGL-specific requirements (WASM MIME types, compression headers) with varying degrees of configuration. Cloudflare is the simplest to set up with a free tier that handles most indie game traffic levels. CloudFront integrates well with S3 hosting and provides fine-grained cache control.
Set cache lifetimes based on how frequently you update the game. Asset files (WASM, data, framework) should have long cache lifetimes (1 year) with cache-busting through filename hashing. Unity's WebGL builds include hashes in filenames by default, so updated builds produce new filenames that the CDN fetches fresh. The HTML page and loader script should have shorter cache lifetimes (1-24 hours) so players receive the latest version reference promptly after an update.
If you use Unity's Data Caching feature, which stores downloaded assets in the browser's IndexedDB for faster subsequent loads, ensure the CDN passes through the correct Content-Length headers. Data Caching uses these to validate cached data integrity.
Step 4: Submit to Game Portals
Game portals provide immediate access to established audiences of browser game players. Each portal has different submission requirements, audience demographics, and monetization approaches.
Itch.io is the most developer-friendly platform. Upload a zip file of your WebGL build, set a page layout, and publish. Itch.io allows free games, pay-what-you-want, and fixed-price models. The platform takes no mandatory revenue share, though developers can set a voluntary split. Itch.io's audience skews toward indie game enthusiasts who are willing to try experimental and niche titles. Maximum upload size is 1 GB for most accounts.
CrazyGames specializes in browser games with ad-based monetization. They provide an SDK for integrating pre-roll and interstitial ads, rewarded video ads, and in-game banner placements. Revenue is shared through a CPM model, with rates varying by geography and game category. CrazyGames handles ad implementation, so the developer focuses on indicating when ad breaks are appropriate (between levels, after game over, etc.).
Poki is another major browser game platform with a similar ad-based model. Their SDK requires games to signal when ad breaks can occur and provides callbacks for pausing gameplay during ads. Poki curates their catalog more selectively than itch.io, so submission involves a review process that evaluates game quality, performance, and audience fit.
Newgrounds maintains an active community of game creators and players with a culture rooted in indie and experimental content. Games are rated by community members, and popular titles receive significant traffic from the front page. Newgrounds provides an API for achievements, scoreboards, and ad mediation. The audience tends to be more engaged and willing to play longer sessions compared to casual game portals.
Step 5: Implement Analytics and Monitoring
Without analytics, you cannot know how players interact with your game, where they drop off, or what content they enjoy. Web games have access to the same analytics tools as any website, plus game-specific metrics.
Google Analytics (GA4) tracks page views, session duration, and user geography out of the box. For game-specific events, use Unity's JavaScript interop to send custom events: level completions, game-over events, feature interactions, and performance metrics. A simple JavaScript plugin (.jslib file) can expose a SendAnalyticsEvent(eventName, eventData) function that calls gtag('event', ...) from within C# game code.
Error monitoring catches crashes and exceptions that players experience but do not report. Services like Sentry, LogRocket, or Bugsnag can intercept JavaScript errors and WebAssembly crashes, providing stack traces, browser information, and user context. For WebGL games, common runtime errors include memory allocation failures (out of memory on mobile), shader compilation failures (unsupported WebGL features), and asset loading failures (network errors, CORS issues).
Performance monitoring tracks real-world frame rates across your player base. Log average FPS, frame time percentiles (p50, p95, p99), and load times by device category (desktop, mobile, tablet) and browser. This data identifies which devices and browsers need targeted optimization and informs decisions about minimum hardware requirements.
Step 6: Set Up Monetization
Web game monetization typically uses advertising, since the browser does not support the app store in-app purchase infrastructure. Several approaches work for different game types and audience sizes.
Display advertising through Google AdSense or similar networks places banner ads around the game canvas. This is the simplest monetization approach: add the ad script to the hosting page, define ad placement divs, and earn revenue from impressions and clicks. Revenue depends on traffic volume, player geography, and ad engagement. A game with 10,000 daily players from primarily US traffic might generate $5-15 per day from display ads.
Rewarded video ads offer players in-game benefits (extra lives, power-ups, currency) in exchange for watching a short video ad. These produce higher revenue per impression than display ads because advertisers pay more for completed views. Implement rewarded ads through portal SDKs (CrazyGames, Poki) or directly through ad networks like Google AdMob for web. The game signals when a rewarded ad opportunity is available, the player chooses to watch, and the game grants the reward upon completion.
Premium models work on platforms that support payment. Itch.io allows fixed pricing or pay-what-you-want. Developers can offer a free web version with ads alongside a premium, ad-free downloadable version. This hybrid approach uses the web version as a demo that funnels interested players toward the paid version.
Sponsorship deals with game portals can provide upfront payment in exchange for exclusive or timed-exclusive distribution rights. Established portals sometimes license games for a flat fee, providing the developer with guaranteed income while the portal earns through advertising. These deals typically range from $500 to $10,000 depending on game quality, genre, and the portal's audience size.
Publishing to the web is a distribution advantage, not just a technical step. Proper server configuration ensures fast loading, game portals provide immediate audience access, and analytics inform ongoing improvements. Treat publishing as a continuous process of optimizing the path from discovery to gameplay.