From 4bd3a59804aedfab15d98faf8130aae6d42fd39d Mon Sep 17 00:00:00 2001 From: Mateusz Wiktor Date: Thu, 29 Oct 2026 12:11:38 +0100 Subject: [PATCH] docs: add JavaScript SDK quickstart and publish snippets Adds the snippets behind the new JavaScript SDK docs IA. New files in docs-snippets/: - quickstart-web.ts, quickstart-web.html - quickstart-node.ts, quickstart-node.mjs - quickstart-react.tsx, quickstart-react-app.tsx - quickstart-commands.sh Extended files: - basic-usage/configuration.ts: setUserId, getUserId, getAuthKey, destroy - publish-subscribe.ts: publishMinimal, publishHandleErrors, publishFalsyMessage Co-Authored-By: Claude Sonnet 5.5 --- docs-snippets/basic-usage/configuration.ts | 16 ++++++ docs-snippets/publish-subscribe.ts | 38 +++++++++++++ docs-snippets/quickstart-commands.sh | 21 ++++++++ docs-snippets/quickstart-node.mjs | 39 ++++++++++++++ docs-snippets/quickstart-node.ts | 38 +++++++++++++ docs-snippets/quickstart-react-app.tsx | 52 ++++++++++++++++++ docs-snippets/quickstart-react.tsx | 63 ++++++++++++++++++++++ docs-snippets/quickstart-web.html | 56 +++++++++++++++++++ docs-snippets/quickstart-web.ts | 53 ++++++++++++++++++ 9 files changed, 376 insertions(+) create mode 100644 docs-snippets/quickstart-commands.sh create mode 100644 docs-snippets/quickstart-node.mjs create mode 100644 docs-snippets/quickstart-node.ts create mode 100644 docs-snippets/quickstart-react-app.tsx create mode 100644 docs-snippets/quickstart-react.tsx create mode 100644 docs-snippets/quickstart-web.html create mode 100644 docs-snippets/quickstart-web.ts diff --git a/docs-snippets/basic-usage/configuration.ts b/docs-snippets/basic-usage/configuration.ts index 6d8f7583a..b6d5a359c 100644 --- a/docs-snippets/basic-usage/configuration.ts +++ b/docs-snippets/basic-usage/configuration.ts @@ -41,3 +41,19 @@ const pubnubConfig = new PubNub({ }); // snippet.end + +// snippet.setUserIdBasicUsage +pubnub.setUserId('myUniqueUserId'); +// snippet.end + +// snippet.getUserIdBasicUsage +const currentUserId = pubnub.getUserId(); +// snippet.end + +// snippet.getAuthKeyBasicUsage +const currentAuthKey = pubnub.getAuthKey(); +// snippet.end + +// snippet.destroyBasicUsage +pubnub.destroy(); +// snippet.end diff --git a/docs-snippets/publish-subscribe.ts b/docs-snippets/publish-subscribe.ts index 8a3893800..461e01626 100644 --- a/docs-snippets/publish-subscribe.ts +++ b/docs-snippets/publish-subscribe.ts @@ -48,6 +48,44 @@ try { } // snippet.end +// snippet.publishMinimal +const { timetoken } = await pubnub.publish({ + channel: 'my_channel', + message: { text: 'Hello' }, +}); + +console.log(timetoken); // "17918851187695440" (a string) +// snippet.end + +// snippet.publishHandleErrors +try { + await pubnub.publish({ + channel: 'my_channel', + message: { text: 'Hello' }, + }); +} catch (e) { + const status = (e as PubNubError).status; + + if (status?.category === 'PNValidationErrorCategory') { + console.error('The call is invalid:', status.message); + } else if (status?.category === 'PNAccessDeniedCategory') { + console.error('403: the token or authKey has no write permission on the channel'); + } else if (status?.category === 'PNNetworkIssuesCategory') { + console.error('The network is unreachable. Retry the publish yourself.'); + } else { + console.error(status?.category, status?.statusCode, status?.errorData); + } +} +// snippet.end + +// snippet.publishFalsyMessage +// message: 0 is rejected with "Missing 'message'", so wrap the value +await pubnub.publish({ + channel: 'my_channel', + message: { value: 0 }, +}); +// snippet.end + // snippet.publishSuccessfull const response = await pubnub.publish({ message: 'hello world!', diff --git a/docs-snippets/quickstart-commands.sh b/docs-snippets/quickstart-commands.sh new file mode 100644 index 000000000..76130a5b6 --- /dev/null +++ b/docs-snippets/quickstart-commands.sh @@ -0,0 +1,21 @@ +#!/bin/sh +# Shell commands for the JavaScript quickstarts. This file is not run as a script. +# Each command group is embedded on its own through the snippet ids below. + +# snippet.quickstartInstallPackage +npm install pubnub +# snippet.end + +# snippet.quickstartNodeInstall +mkdir pubnub-quickstart +cd pubnub-quickstart +npm install pubnub +# snippet.end + +# snippet.quickstartNodeRun +node index.mjs +# snippet.end + +# snippet.quickstartCloneSource +git clone https://github.com/pubnub/javascript +# snippet.end diff --git a/docs-snippets/quickstart-node.mjs b/docs-snippets/quickstart-node.mjs new file mode 100644 index 000000000..27114666e --- /dev/null +++ b/docs-snippets/quickstart-node.mjs @@ -0,0 +1,39 @@ +import PubNub from 'pubnub'; + +const pubnub = new PubNub({ + publishKey: 'YOUR_PUBLISH_KEY', + subscribeKey: 'YOUR_SUBSCRIBE_KEY', + userId: 'YOUR_USER_ID', +}); + +pubnub.addListener({ + message: (event) => { + console.log(`Received on ${event.channel}: ${event.message}`); + }, + status: (event) => { + if (event.category === 'PNConnectedCategory') { + console.log('Connected to PubNub'); + } + }, +}); + +// Create a channel entity +const channel = pubnub.channel('hello_world'); + +// Create a subscription +const subscription = channel.subscription({ + receivePresenceEvents: true, // to receive presence events +}); + +// Subscribe +subscription.subscribe(); + +try { + const result = await pubnub.publish({ + channel: 'hello_world', + message: 'Hello, world!', + }); + console.log(`Published, timetoken: ${result.timetoken}`); +} catch (error) { + console.error(`Publish failed: ${error}`); +} diff --git a/docs-snippets/quickstart-node.ts b/docs-snippets/quickstart-node.ts new file mode 100644 index 000000000..d8675adf3 --- /dev/null +++ b/docs-snippets/quickstart-node.ts @@ -0,0 +1,38 @@ +import PubNub from '../lib/types'; + +// The Node.js quickstart runs as an ES module (index.mjs), so the import line comes from +// docs-snippets/import-pubnub.ts (importPubNub) and the initialization comes from +// docs-snippets/getting-started.ts (gettingStartedInitPubnub and gettingStartedCreateSubscription). +// The import above only lets the compiler check the snippets below. +// The runnable file that combines them all is docs-snippets/quickstart-node.mjs. + +const pubnub = new PubNub({ + publishKey: 'YOUR_PUBLISH_KEY', + subscribeKey: 'YOUR_SUBSCRIBE_KEY', + userId: 'YOUR_USER_ID', +}); + +// snippet.quickstartNodeListeners +pubnub.addListener({ + message: (event) => { + console.log(`Received on ${event.channel}: ${event.message}`); + }, + status: (event) => { + if (event.category === 'PNConnectedCategory') { + console.log('Connected to PubNub'); + } + }, +}); +// snippet.end + +// snippet.quickstartNodePublish +try { + const result = await pubnub.publish({ + channel: 'hello_world', + message: 'Hello, world!', + }); + console.log(`Published, timetoken: ${result.timetoken}`); +} catch (error) { + console.error(`Publish failed: ${error}`); +} +// snippet.end diff --git a/docs-snippets/quickstart-react-app.tsx b/docs-snippets/quickstart-react-app.tsx new file mode 100644 index 000000000..487576fba --- /dev/null +++ b/docs-snippets/quickstart-react-app.tsx @@ -0,0 +1,52 @@ +import { useEffect, useState } from 'react'; +import PubNub from 'pubnub'; + +// Create the client once, outside the component, so re-renders reuse it +const pubnub = new PubNub({ + publishKey: 'YOUR_PUBLISH_KEY', + subscribeKey: 'YOUR_SUBSCRIBE_KEY', + userId: 'YOUR_USER_ID', +}); + +export default function App() { + const [messages, setMessages] = useState([]); + + useEffect(() => { + const subscription = pubnub.channel('hello_world').subscription(); + + subscription.onMessage = (event) => { + setMessages((previous) => [...previous, `${event.publisher}: ${event.message}`]); + }; + subscription.subscribe(); + + // Runs on unmount, and before React re-runs the effect in development (StrictMode) + return () => { + subscription.unsubscribe(); + }; + }, []); + + const [text, setText] = useState(''); + + const send = async () => { + if (!text.trim()) return; + + try { + await pubnub.publish({ channel: 'hello_world', message: text }); + setText(''); + } catch (error) { + console.error(`Publish failed: ${error}`); + } + }; + + return ( +
+
    + {messages.map((message, index) => ( +
  • {message}
  • + ))} +
+ setText(event.target.value)} placeholder="Type a message" /> + +
+ ); +} diff --git a/docs-snippets/quickstart-react.tsx b/docs-snippets/quickstart-react.tsx new file mode 100644 index 000000000..c7b347d13 --- /dev/null +++ b/docs-snippets/quickstart-react.tsx @@ -0,0 +1,63 @@ +// snippet.quickstartReactImports +import { useEffect, useState } from 'react'; +import PubNub from 'pubnub'; +// snippet.end + +// The React quickstart embeds the snippets below one by one. +// The complete file that combines them is docs-snippets/quickstart-react-app.tsx. +// This file is TSX, so docs-snippets/tsconfig.json (which only includes .ts files) does not compile it. + +// snippet.quickstartReactInit +// Create the client once, outside the component, so re-renders reuse it +const pubnub = new PubNub({ + publishKey: 'YOUR_PUBLISH_KEY', + subscribeKey: 'YOUR_SUBSCRIBE_KEY', + userId: 'YOUR_USER_ID', +}); +// snippet.end + +export function Subscribe() { + // snippet.quickstartReactSubscribe + const [messages, setMessages] = useState([]); + + useEffect(() => { + const subscription = pubnub.channel('hello_world').subscription(); + + subscription.onMessage = (event) => { + setMessages((previous) => [...previous, `${event.publisher}: ${event.message}`]); + }; + subscription.subscribe(); + + // Runs on unmount, and before React re-runs the effect in development (StrictMode) + return () => { + subscription.unsubscribe(); + }; + }, []); + // snippet.end + + return
    {messages.map((message, index) =>
  • {message}
  • )}
; +} + +export function Publish() { + // snippet.quickstartReactPublish + const [text, setText] = useState(''); + + const send = async () => { + if (!text.trim()) return; + + try { + await pubnub.publish({ channel: 'hello_world', message: text }); + setText(''); + } catch (error) { + console.error(`Publish failed: ${error}`); + } + }; + // snippet.end + + return ( + <> + setText(event.target.value)} /> + + + ); +} diff --git a/docs-snippets/quickstart-web.html b/docs-snippets/quickstart-web.html new file mode 100644 index 000000000..93d255c62 --- /dev/null +++ b/docs-snippets/quickstart-web.html @@ -0,0 +1,56 @@ + + + + + PubNub quickstart + + + +

PubNub quickstart

+
    + + + + + + diff --git a/docs-snippets/quickstart-web.ts b/docs-snippets/quickstart-web.ts new file mode 100644 index 000000000..a349fdf2f --- /dev/null +++ b/docs-snippets/quickstart-web.ts @@ -0,0 +1,53 @@ +import PubNub from '../lib/types'; + +// The Web quickstart loads the SDK from the CDN, which exposes the PubNub global. +// The import above only lets the compiler check the snippets below. +// The runnable page that combines them is docs-snippets/quickstart-web.html. + +// snippet.quickstartWebInit +const pubnub = new PubNub({ + publishKey: 'YOUR_PUBLISH_KEY', + subscribeKey: 'YOUR_SUBSCRIBE_KEY', + userId: 'YOUR_USER_ID', +}); +// snippet.end + +// snippet.quickstartWebListeners +pubnub.addListener({ + message: (event) => { + // Add every incoming message to the list on the page + const item = document.createElement('li'); + item.textContent = `${event.publisher}: ${event.message}`; + document.querySelector('ul')?.append(item); + }, + status: (event) => { + if (event.category === 'PNConnectedCategory') { + console.log('Connected to PubNub'); + } + }, +}); +// snippet.end + +// snippet.quickstartWebSubscribe +const channel = pubnub.channel('hello_world'); +const subscription = channel.subscription(); +subscription.subscribe(); +// snippet.end + +// snippet.quickstartWebPublish +document.querySelector('button')?.addEventListener('click', async () => { + const input = document.querySelector('input'); + if (!input || !input.value.trim()) return; + + try { + const result = await pubnub.publish({ + channel: 'hello_world', + message: input.value, + }); + console.log(`Published, timetoken: ${result.timetoken}`); + input.value = ''; + } catch (error) { + console.error(`Publish failed: ${error}`); + } +}); +// snippet.end