Messages and types
This page covers how incoming data is decoded and validated, how outgoing messages are encoded, and how to type both directions.
Raw data by default
Without options, messages are delivered exactly as the browser gives them in event.data: a string for text frames, and a Blob (or ArrayBuffer) for binary frames. send() passes its argument straight to WebSocket.send.
JSON
json: true runs JSON.parse on incoming data and JSON.stringify on outgoing messages:
The two type parameters are:
In: the type of incoming messages, after decoding. It typeslastMessage,onMessageand themessageevent.Out: the type thatsend()accepts.
useWebSocket<ServerEvent> only tells TypeScript what to expect. Nothing checks it at runtime. To check incoming data, use a schema.
Custom encoding
parse and serialize replace the default (or JSON) encoding. They take precedence over json.
binaryType controls how binary frames arrive: 'blob' (the browser default) or 'arraybuffer'. Use 'arraybuffer' when you decode binary synchronously in parse.
Validating with a schema
schema accepts any Standard Schema validator, including zod (3.24+), valibot (1.0+) and arktype (2.0+). The schema runs after parse/json, and the incoming message type is inferred from it, so you don't need to pass In yourself:
The delivered message is the schema's output, so transforms and defaults apply:
Async schemas (for example zod's refine with an async check) are supported. Messages are still delivered in the order they arrived, even if a later one validates faster.
One socket, many message types
Many servers send several kinds of messages over one socket. Use a discriminated union, either as a type or as a schema, and narrow on the tag:
More patterns are in Recipes.
Invalid messages: MessageError
A message that fails to decode (parse throws, or json gets invalid JSON) or fails schema is not delivered. lastMessage isn't updated and onMessage isn't called. Instead, an error event is emitted with a MessageError:
The connection stays open after a MessageError; only that message is dropped.
Outgoing messages
send(message) encodes with serialize, or JSON.stringify if json is set, or passes the message through unchanged. If the socket isn't open yet, the encoded message is queued and sent when it opens. See the send queue.
send returns true if the message went out immediately and false if it was queued (or dropped, with queue: false).
Outgoing messages are not validated by schema. The Out type parameter covers them at compile time.
See also
- Options:
json,parse,serialize,schema,binaryType - Types:
MessageError,StandardSchemaV1,SendData