1"use strict";(self.webpackChunksample_website=self.webpackChunksample_website||[]).push([[1071],{3905:(e,n,t)=>{t.d(n,{Zo:()=>p,kt:()=>k});var a=t(7294);function o(e,n,t){return n in e?Object.defineProperty(e,n,{value:t,enumerable:!0,configurable:!0,writable:!0}):e[n]=t,e}function s(e,n){var t=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);n&&(a=a.filter((function(n){return Object.getOwnPropertyDescriptor(e,n).enumerable}))),t.push.apply(t,a)}return t}function c(e){for(var n=1;n<arguments.length;n++){var t=null!=arguments[n]?arguments[n]:{};n%2?s(Object(t),!0).forEach((function(n){o(e,n,t[n])})):Object.getOwnPropertyDescriptors?Object.defineProperties(e,Object.getOwnPropertyDescriptors(t)):s(Object(t)).forEach((function(n){Object.defineProperty(e,n,Object.getOwnPropertyDescriptor(t,n))}))}return e}function r(e,n){if(null==e)return{};var t,a,o=function(e,n){if(null==e)return{};var t,a,o={},s=Object.keys(e);for(a=0;a<s.length;a++)t=s[a],n.indexOf(t)>=0||(o[t]=e[t]);return o}(e,n);if(Object.getOwnPropertySymbols){var s=Object.getOwnPropertySymbols(e);for(a=0;a<s.length;a++)t=s[a],n.indexOf(t)>=0||Object.prototype.propertyIsEnumerable.call(e,t)&&(o[t]=e[t])}return o}var i=a.createContext({}),l=function(e){var n=a.useContext(i),t=n;return e&&(t="function"==typeof e?e(n):c(c({},n),e)),t},p=function(e){var n=l(e.components);return a.createElement(i.Provider,{value:n},e.children)},m="mdxType",u={inlineCode:"code",wrapper:function(e){var n=e.children;return a.createElement(a.Fragment,{},n)}},d=a.forwardRef((function(e,n){var t=e.components,o=e.mdxType,s=e.originalType,i=e.parentName,p=r(e,["components","mdxType","originalType","parentName"]),m=l(t),d=o,k=m["".concat(i,".").concat(d)]||m[d]||u[d]||s;return t?a.createElement(k,c(c({ref:n},p),{},{components:t})):a.createElement(k,c({ref:n},p))}));function k(e,n){var t=arguments,o=n&&n.mdxType;if("string"==typeof e||o){var s=t.length,c=new Array(s);c[0]=d;var r={};for(var i in n)hasOwnProperty.call(n,i)&&(r[i]=n[i]);r.originalType=e,r[m]="string"==typeof e?e:o,c[1]=r;for(var l=2;l<s;l++)c[l]=t[l];return a.createElement.apply(null,c)}return a.createElement.apply(null,t)}d.displayName="MDXCreateElement"},7091:(e,n,t)=>{t.r(n),t.d(n,{assets:()=>i,contentTitle:()=>c,default:()=>u,frontMatter:()=>s,metadata:()=>r,toc:()=>l});var a=t(3117),o=(t(7294),t(3905));const s={title:"Namespaces",sidebar_position:1,slug:"/namespaces/"},c=void 0,r={unversionedId:"categories/Advanced/namespaces",id:"version-3.x/categories/Advanced/namespaces",title:"Namespaces",description:'A Namespace is a communication channel that allows you to split the logic of your application over a single shared connection (also called "multiplexing").',source:"@site/versioned_docs/version-3.x/categories/05-Advanced/namespaces.md",sourceDirName:"categories/05-Advanced",slug:"/namespaces/",permalink:"/docs/v3/namespaces/",draft:!1,editUrl:"https://github.com/socketio/socket.io-website/edit/main/versioned_docs/version-3.x/categories/05-Advanced/namespaces.md",tags:[],version:"3.x",lastUpdatedAt:1784117104,formattedLastUpdatedAt:"Jul 15, 2026",sidebarPosition:1,frontMatter:{title:"Namespaces",sidebar_position:1,slug:"/namespaces/"},sidebar:"version-3.x/sidebar",previous:{title:"Emit cheatsheet",permalink:"/docs/v3/emit-cheatsheet/"},next:{title:"Custom parser",permalink:"/docs/v3/custom-parser/"}},i={},l=[{value:"Introduction",id:"introduction",level:2},{value:"Main namespace",id:"main-namespace",level:2},{value:"Custom namespaces",id:"custom-namespaces",level:2},{value:"Client initialization",id:"client-initialization",level:2},{value:"Dynamic namespaces",id:"dynamic-namespaces",level:2},{value:"Complete API",id:"complete-api",level:2}],p={toc:l},m="wrapper";
1function u(e){let{components:n,...s}=e;return(0,o.kt)(m,(0,a.Z)({},p,s,{components:n,mdxType:"MDXLayout"}),(0,o.kt)("p",null,'A Namespace is a communication channel that allows you to split the logic of your application over a single shared connection (also called "multiplexing").'),(0,o.kt)("p",null,(0,o.kt)("img",{alt:"Namespace diagram",src:t(1578).Z,width:"1321",height:"326"})),(0,o.kt)("h2",{id:"introduction"},"Introduction"),(0,o.kt)("p",null,"Each namespace has its own:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v3/listening-to-events/"},"event handlers"))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'io.of("/orders").on("connection", (socket) => {\n socket.on("order:list", () => {});\n socket.on("order:create", () => {});\n});\n\nio.of("/users").on("connection", (socket) => {\n socket.on("user:list", () => {});\n});\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v3/rooms/"},"rooms"))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const orderNamespace = io.of("/orders");\n\norderNamespace.on("connection", (socket) => {\n socket.join("room1");\n orderNamespace.to("room1").emit("hello");\n});\n\nconst userNamespace = io.of("/users");\n\nuserNamespace.on("connection", (socket) => {\n socket.join("room1"); // distinct from the room in the "orders" namespace\n userNamespace.to("room1").emit("hol\xe0");\n});\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v3/middlewares/"},"middlewares"))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const orderNamespace = io.of("/orders");\n\norderNamespace.use((socket, next) => {\n // ensure the socket has access to the "orders" namespace, and then\n next();\n});\n\nconst userNamespace = io.of("/users");\n\nuserNamespace.use((socket, next) => {\n // ensure the socket has access to the "users" namespace, and then\n next();\n});\n')),(0,o.kt)("p",null,"Possible use cases:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"you want to create a special namespace that only authorized users have access to, so the logic related to those users is separated from the rest of the application")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const adminNamespace = io.of("/admin");\n\nadminNamespace.use((socket, next) => {\n // ensure the user has sufficient rights\n next();\n});\n\nadminNamespace.on("connection", socket => {\n socket.on("delete user", () => {\n // ...\n });\n});\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"your application has multiple tenants so you want to dynamically create one namespace per tenant")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const workspaces = io.of(/^\\/\\w+$/);\n\nworkspaces.on("connection", socket => {\n const workspace = socket.nsp;\n\n workspace.emit("hello");\n});\n')),(0,o.kt)("h2",{id:"main-namespace"},"Main namespace"),(0,o.kt)("p",null,"Until now, you interacted with the main namespace, called ",(0,o.kt)("inlineCode",{parentName:"p"},"/"),". The ",(0,o.kt)("inlineCode",{parentName:"p"},"io")," instance inherits all of its methods:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'io.on("connection", (socket) => {});\nio.use((socket, next) => { next() });\nio.emit("hello");\n// are actually equivalent to\nio.of("/").on("connection", (socket) => {});\nio.of("/").use((socket, next) => { next() });\nio.of("/").emit("hello");\n')),(0,o.kt)("p",null,"Some tutorials may also mention ",(0,o.kt)("inlineCode",{parentName:"p"},"io.sockets"),", it's simply an alias for ",(0,o.kt)("inlineCode",{parentName:"p"},'io.of("/")'),"."),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'io.sockets === io.of("/")\n')),(0,o.kt)("h2",{id:"custom-namespaces"},"Custom namespaces"),(0,o.kt)("p",null,"To set up a custom namespace, you can call the ",(0,o.kt)("inlineCode",{parentName:"p"},"of")," function on the server-side:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const nsp = io.of("/my-namespace");\n\nnsp.on("connection", socket => {\n console.log("someone connected");\n});\n\nnsp.emit("hi", "everyone!");\n')),(0,o.kt)("h2",{id:"client-initialization"},"Client initialization"),(0,o.kt)("p",null,"Same-origin version:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const socket = io(); // or io("/"), the main namespace\nconst orderSocket = io("/orders"); // the "orders" namespace\nconst userSocket = io("/users"); // the "users" namespace\n')),(0,o.kt)("p",null,"Cross-origin/Node.js version:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const socket = io("https://example.com"); // or io("https://example.com/"), the main namespace\nconst orderSocket = io("https://example.com/orders"); // the "orders" namespace\nconst userSocket = io("https://example.com/users"); // the "users" namespace\n')),(0,o.kt)("p",null,"In the example above, only one WebSocket connection will be established, and the packets will automatically be routed to the right namespace."),(0,o.kt)("p",null,"Please note that multiplexing will be disabled in the following cases:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"multiple creation for the same namespace")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"const socket1 = io();\nconst socket2 = io(); // no multiplexing, two distinct WebSocket connections\n")),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"different domains")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const socket1 = io("https://first.example.com");\nconst socket2 = io("https://second.example.com"); // no multiplexing, two distinct WebSocket connections\n')),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"usage of the ",(0,o.kt)("a",{parentName:"li",href:"/docs/v3/client-initialization/#forceNew"},"forceNew")," option")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const socket1 = io();\nconst socket2 = io("/admin", { forceNew: true }); // no multiplexing, two distinct WebSocket connections\n')),(0,o.kt)("h2",{id:"dynamic-namespaces"},"Dynamic namespaces"),(0,o.kt)("p",null,"It is also possible to dynamically create namespaces, either with a regular expression:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"io.of(/^\\/dynamic-\\d+$/);\n")),(0,o.kt)("p",null,"or with a function:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"io.of((name, auth, next) => {\n next(null, true); // or false, when the creation is denied\n});\n")),(0,o.kt)("p",null,"You can have access to the new namespace in the ",(0,o.kt)("inlineCode",{parentName:"p"},"connection")," event:"),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'io.of(/^\\/dynamic-\\d+$/).on("connection", (socket) => {\n const namespace = socket.nsp;\n});\n')),(0,o.kt)("p",null,"The return value of the ",(0,o.kt)("inlineCode",{parentName:"p"},"of()")," method is what we call the parent namespace, from which you can:"),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},"register ",(0,o.kt)("a",{parentName:"li",href:"/docs/v3/middlewares/"},"middlewares"))),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},"const parentNamespace = io.of(/^\\/dynamic-\\d+$/);\n\nparentNamespace.use((socket, next) => { next() });\n")),(0,o.kt)("p",null,"The middleware will automatically be registered on each child namespace."),(0,o.kt)("ul",null,(0,o.kt)("li",{parentName:"ul"},(0,o.kt)("a",{parentName:"li",href:"/docs/v3/broadcasting-events/"},"broadcast")," events")),(0,o.kt)("pre",null,(0,o.kt)("code",{parentName:"pre",className:"language-js"},'const parentNamespace = io.of(/^\\/dynamic-\\d+$/);\n\nparentNamespace.emit("hello"); // will be sent to users in /dynamic-1, /dynamic-2, ...\n')),(0,o.kt)("h2",{id:"complete-api"},"Complete API"),(0,o.kt)("p",null,"The complete API exposed by the Namespace instance can be found ",(0,o.kt)("a",{parentName:"p",href:"/docs/v3/server-api/#Namespace"},"here"),"."))}u.isMDXComponent=!0},1578:(e,n,t)=>{t.d(n,{Z:()=>a});const a=t.p+"assets/images/namespaces-088745a8a8882118740f50b6b1232588.png"}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.