Setting user agents in browser environments
Overview
When using Speakeasy SDKs in browser environments, setting the user agent header directly is restricted by browser security policies. This guide demonstrates how to use SDK hooks to set user agent information in a browser-compatible way.
Understanding the challenge
Browsers prevent direct modification of the User-Agent
header for security reasons. When attempting to set this header in browser environments:
- The header modification may silently fail
- No error will be thrown
- The original browser user agent will be used instead
Solution using SDK hooks
We can use a BeforeRequestHook
to implement a fallback mechanism that ensures our SDK version information is properly transmitted, even in browser environments.
import { BeforeRequestContext, BeforeRequestHook, Awaitable } from "./types";import { SDK_METADATA } from "../lib/config";export class CustomUserAgentHook implements BeforeRequestHook {beforeRequest(_: BeforeRequestContext, request: Request): Awaitable<Request> {const version = SDK_METADATA.sdkVersion;const ua = `speakeasy-sdk/${version}`;// Try to set the standard user-agent header firstrequest.headers.set("user-agent", ua);// Check if the header was actually set (it may silently fail in browsers)if (!request.headers.get("user-agent")) {// Fall back to a custom header if the user-agent couldn't be setrequest.headers.set("x-sdk-user-agent", ua);}return request;}}
How the hook works
- The hook attempts to set the standard
user-agent
header first - It then checks if the header was successfully set
- If the header wasn’t set (which happens in browsers), it falls back to using a custom header
x-sdk-user-agent
- This ensures your SDK version information is always transmitted, regardless of browser restrictions
Adding the hook to your SDK
Register the hook in your SDK’s hook registration file:
import { CustomUserAgentHook } from "./user_agent";import { Hooks } from "./types";export function initHooks(hooks: Hooks) {hooks.registerBeforeRequestHook(new CustomUserAgentHook());}
Using hooks with generated SDKs
When working with SDKs generated by Speakeasy, you’ll want to follow these best practices:
- Always implement the fallback mechanism to handle browser environments
- Use a consistent format for your user agent string (e.g.,
sdk-name/version
) - Consider including additional relevant information in the user agent string
- Test the implementation in both browser and non-browser environments
This approach ensures your Speakeasy SDK can properly identify itself to your API while remaining compatible with browser security restrictions.