How to configure CORS for Pley

Cross-Origin Resource Sharing (CORS) headers is required for your server to communicate with web browsers.

When your game runs on Pley, it needs to communicate with your backend server. Browsers enforce a security rule called CORS (Cross-Origin Resource Sharing) to allow this. You don't have to set the CORS headers on mobile as the app is not running in a browser. To communicate with web browsers, you’ll need to configure your server to send requests acceptable by browers on Pley’s domain: https://*.pley.games. Here’s how to do it, even if you’re new to web development.

What You Need to Do

Configure your server to:

  1. Allow requests from https://*.pley.games. All Pley requests come through [GameID].pley.games. Note that how this is configured depends on your service or server. Wildcard character support varies.
  2. Permit common methods like GET, POST, and OPTIONS.
  3. Add the right CORS headers to its responses.

How-to:

  1. Find Your Server Config: Look for where your backend handles requests (e.g., code, settings, or a dashboard).
  2. Set Allowed Origins: Add https://*.pley.games as an allowed origin.
  3. Define Allowed Methods: Include at least GET, POST, and OPTIONS.
  4. Return CORS Headers: Ensure responses include Access-Control-Allow-Origin with the Pley domain.
  5. Testing: You can test your implementation by launching the game on the web and opening the browser developer console (CTRL+Shift+i or F12 opens the menu on Windows in most browsers. Cmd + Opt + i on Mac.) If CORS is working, there should be no cross-origin related errors. Example:

Examples

Since every server is different, here are some examples. Adjust these to fit your setup.

  • It is viable for nearly every service and server to simply allow all origins using *
  • For services which supports it, https://*.pley.games work.
  • If your service require a specific domain, which isn't uncommon, allow the https://[GameID].pley.games origin. The game ID can be found in the Game Manager under Game -> Project Settings.

Amazon S3 and Cloudfront

If your game files are on a service like Amazon S3, update its CORS policy. Paste this into your S3 bucket’s CORS settings. It tells S3 to allow Pley to access your game files. Since AWS supports wildcard characters (*) in the left-most position, the config is very simple. Here’s a sample config:

[
  {
    "AllowedMethods": ["GET", "PUT", "POST"],
    "AllowedOrigins": ["https://*.pley.games"]
  }
]

AWS S3 Documentation

AWS CloudFront Documentation


Custom Server (C# Backend)

If you run a custom server, you’ll need to check the request’s Origin header and return the appropriate CORS headers back to the browser. This tells the browser which origins, methods, and headers your API allows.

To maximize compatibility across browsers and avoid subtle issues, we recommend explicitly listing all HTTP headers your API expects or returns, using comma-separated lists. For example:

Access-Control-Allow-Headers: Content-Type, Authorization, X-My-Custom-Header
Access-Control-Expose-Headers: X-Total-Count, X-RateLimit-Remaining

Some systems support allowing all headers using the wildcard *. If your server supports this, you can choose to allow all. A common approach to safely support this is to programmatically verify that the incoming Origin ends with .pley.games. While using * may work in some cases, it is not consistently supported by all browsers or server environments. Explicit header lists are more predictable and safer, especially when using custom request or response headers.

Below is a simple C# example showing how to check the Origin and return basic CORS headers. This example allows any request where the origin ends with .pley.games and adds preflight (OPTIONS) response headers:

const string ORIGIN_HEADER = "Origin";
const string PLEY_HOST_ENDING = "pley.games";

public static void AddCorsHeaderToResponse(
  string requestMethod, IDictionary<string, string> requestHeaders, APIGatewayProxyResponse response)
{
    // Attempt to read the Origin header
    if (!requestHeaders.TryGetValue(ORIGIN_HEADER, out var requestOrigin))
    {
        // No Origin header found—nothing to do
        return;
    }

    // Ensure only origins ending with .pley.games are allowed
    if (!requestOrigin.EndsWith(PLEY_HOST_ENDING))
    {
        return;
    }

    if (response.Headers == null)
        response.Headers = new Dictionary<string, string>();

    // Allow this specific origin
    response.Headers.Add("Access-Control-Allow-Origin", requestOrigin);

    // Handle the CORS preflight request
    if (requestMethod == "OPTIONS")
    {
        response.Headers.Add("Access-Control-Allow-Methods", "GET, POST, OPTIONS");
        response.Headers.Add("Access-Control-Allow-Headers", "*");
    }
}
📘

Custom Headers

If your server sends custom response headers, they may need to be explicitly listed using Access-Control-Expose-Headers in every response that includes them. This is required when Access-Control-Allow-Headers: * is not supported by the browser or environment.

Access-Control-Allow-Origin: https://yourdomain.pley.games
Access-Control-Allow-Methods: GET, POST, OPTIONS
Access-Control-Allow-Headers: Content-Type, Authorization, X-Custom-Header
Access-Control-Expose-Headers: X-Total-Count, X-RateLimit-Remaining

Read more about CORS here from Moesif for best-practices information.