Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/strophe/strophejs/llms.txt

Use this file to discover all available pages before exploring further.

The Connection class is the central object in Strophe.js. It manages the full lifecycle of an XMPP session — from initial TCP or WebSocket handshake through SASL authentication, resource binding, and eventual disconnection. Every operation in your XMPP client flows through a Connection instance: sending stanzas, registering handlers, and reacting to server-driven events all happen via this class.

Creating a Connection

Instantiate a connection by passing a service URL and an optional configuration object:
// new Strophe.Connection(service: string, options?: ConnectionOptions)
const conn = new Strophe.Connection('wss://xmpp.example.com/xmpp-websocket');
The service parameter determines both the endpoint and the transport protocol. You can also pass a path-only URL when connecting to the same host as the page:
// BOSH via absolute URL
const conn = new Strophe.Connection('https://xmpp.example.com/http-bind/');

// WebSocket via absolute URL
const conn = new Strophe.Connection('wss://xmpp.example.com/xmpp-websocket');

// Path-only — inherits current host, uses BOSH
const conn = new Strophe.Connection('/http-bind/');

// Path-only — force WebSocket using the protocol option
const conn = new Strophe.Connection('/xmpp-websocket/', { protocol: 'wss' });

Transport Selection

Strophe.js automatically selects a transport based on the service URL scheme:
URL prefixTransport
ws:// or wss://WebSocket
http://, https://, or a relative pathBOSH
Relative path + protocol: 'ws' or 'wss' optionWebSocket
When using a relative URL without a protocol prefix, security is never downgraded: if the page is served over HTTPS, Strophe.js will use the secure variant of whichever transport is selected (wss:// or https://).
You can also run a WebSocket connection inside a SharedWorker by supplying the worker option with the URL of the shared worker script. This lets multiple browser tabs share a single underlying WebSocket connection.
const conn = new Strophe.Connection('/xmpp-websocket/', {
  worker: '/js/shared-connection-worker.js',
});

Key Properties

Once a connection is created and in use, several properties expose the current session state:
jid
string
The full JID assigned to this session (e.g. alice@example.com/resource). Empty string before connection.
authzid
string | null
The authorization identity — the bare JID derived from the supplied JID at connect time.
domain
string | null
The XMPP domain extracted from the JID (e.g. example.com). Populated after connect() is called.
connected
boolean
true when the session is fully established and authenticated. Handlers are only dispatched while this is true.
disconnecting
boolean
true while a graceful disconnection is in progress.
paused
boolean
When true, Strophe.js will not send any more requests to the server. Useful for batching multiple send() calls into a single BOSH request. Call conn.pause() / conn.resume() to toggle.
maxRetries
number
The maximum number of connection retries before permanently disconnecting. Defaults to 5.

Connection Status Constants

Every status update delivered to your connect callback uses a numeric constant from Strophe.Status. The full set of values is:
ConstantValueMeaning
Strophe.Status.ERROR0An unrecoverable error occurred.
Strophe.Status.CONNECTING1The connection is being established.
Strophe.Status.CONNFAIL2The connection attempt failed.
Strophe.Status.AUTHENTICATING3SASL authentication is in progress.
Strophe.Status.AUTHFAIL4Authentication failed (bad credentials or no matching mechanism).
Strophe.Status.CONNECTED5The session is fully established and ready to use.
Strophe.Status.DISCONNECTED6The session has ended.
Strophe.Status.DISCONNECTING7A graceful disconnection is in progress.
Strophe.Status.ATTACHED8Successfully attached to a pre-existing BOSH session.
Strophe.Status.REDIRECT9The server sent a redirect.
Strophe.Status.CONNTIMEOUT10The connection timed out.
Strophe.Status.BINDREQUIRED11Resource binding is required; only fired when explicitResourceBinding is true.
Strophe.Status.ATTACHFAIL12Attaching to a BOSH session failed.
Strophe.Status.RECONNECTING13The client is attempting to reconnect after an interruption.
The normal happy path flows through: CONNECTINGAUTHENTICATINGCONNECTED. On failure it branches to CONNFAIL, AUTHFAIL, or ERROR. When you call disconnect(), the sequence is DISCONNECTINGDISCONNECTED.

Connecting and the Status Callback

Call conn.connect() to start a session. The callback you provide will be invoked each time the connection status changes. Return nothing from the callback — it is purely for side effects.
conn.connect(
  jid: string,
  password: string,
  callback?: (status: number, condition: string | null, elem?: Element) => void,
  wait?: number,   // BOSH only: seconds the server waits before returning empty response (default 60)
  hold?: number,   // BOSH only: number of simultaneous connections (default 1)
  route?: string,  // BOSH only: optional route value
  authcid?: string // Alternative authentication identity (for impersonation / EXTERNAL)
)
Here is a complete callback that handles every meaningful status transition:
import { Strophe } from 'strophejs';

const conn = new Strophe.Connection('wss://xmpp.example.com/xmpp-websocket');

function onConnect(status: number, condition: string | null) {
  if (status === Strophe.Status.CONNECTING) {
    console.log('Connecting…');

  } else if (status === Strophe.Status.CONNFAIL) {
    console.error('Connection failed:', condition);

  } else if (status === Strophe.Status.AUTHENTICATING) {
    console.log('Authenticating…');

  } else if (status === Strophe.Status.AUTHFAIL) {
    console.error('Authentication failed:', condition);

  } else if (status === Strophe.Status.CONNECTED) {
    console.log('Connected as', conn.jid);
    // Safe to send stanzas and add handlers here
    conn.send(Strophe.$pres());

  } else if (status === Strophe.Status.DISCONNECTING) {
    console.log('Disconnecting…');

  } else if (status === Strophe.Status.DISCONNECTED) {
    console.log('Disconnected');

  } else if (status === Strophe.Status.RECONNECTING) {
    console.log('Reconnecting…');

  } else if (status === Strophe.Status.CONNTIMEOUT) {
    console.error('Connection timed out');

  } else if (status === Strophe.Status.BINDREQUIRED) {
    // Only fired when options.explicitResourceBinding === true
    console.log('Binding resource explicitly…');
    conn.bind();

  } else if (status === Strophe.Status.ERROR) {
    console.error('Unrecoverable error:', condition);
  }
}

conn.connect('alice@example.com', 's3cr3t', onConnect);

Disconnecting

To end a session gracefully, call disconnect(). You can pass an optional reason string that will be included in the XMPP stream close:
conn.disconnect('user logout');
Strophe.js will send a </stream:stream> close and wait up to disconnection_timeout milliseconds (default 3000) for the server to acknowledge before forcefully tearing down the transport. The callback will receive DISCONNECTING then DISCONNECTED.

Sending Stanzas

Use send() to push a built stanza onto the outgoing queue:
conn.send(stanza: Element | Builder | Array<Element | Builder>): void
Strophe.js batches outgoing data and flushes it on the next idle cycle (every 100 ms). To flush immediately, call conn.flush(). For IQ stanzas, the higher-level sendIQ() helper automatically manages the response handler and supports an optional timeout:
const iqId = conn.sendIQ(
  stanza,
  (result) => console.log('IQ result', result),
  (error) => console.error('IQ error or timeout', error),
  5000 // timeout in ms
);
A similar helper exists for presence: sendPresence().

Debugging with Raw and XML Hooks

Strophe.js exposes four overrideable hooks for inspecting traffic at different levels of abstraction. By default they are no-ops.
// Inspect raw string data received from the transport
conn.rawInput = (data: string) => {
  console.log('IN:', data);
};

// Inspect raw string data sent to the transport
conn.rawOutput = (data: string) => {
  console.log('OUT:', data);
};

// Inspect parsed XML elements as they arrive
conn.xmlInput = (elem: Node | MessageEvent) => {
  console.log('XML IN:', elem);
};

// Inspect parsed XML elements as they are sent
conn.xmlOutput = (elem: Element) => {
  console.log('XML OUT:', elem);
};
Use rawInput / rawOutput when debugging transport-level issues (e.g. BOSH body wrapping or WebSocket framing). Use xmlInput / xmlOutput when you want to see individual XMPP stanzas.

Protocol Error Handlers

You can register a callback for specific HTTP or WebSocket error codes that may occur at the transport layer:
conn.addProtocolErrorHandler('HTTP', 500, (statusCode: number) => {
  console.error('BOSH endpoint returned HTTP 500');
});
Valid protocol values are 'HTTP' (for BOSH) and 'websocket'.

BOSH Session Persistence

When using BOSH with keepalive: true, Strophe.js caches the session tokens (RID and SID) in sessionStorage. On subsequent page loads you can restore the session instead of re-authenticating:
const conn = new Strophe.Connection('/http-bind/', { keepalive: true });

// On reload, try to restore before calling connect()
conn.restore('alice@example.com', onConnect);
You can also attach to a BOSH session that was created server-side (e.g. for auto-login) using conn.attach().

Build docs developers (and LLMs) love