{"id":462446,"date":"2025-06-09T03:03:19","date_gmt":"2025-06-09T03:03:19","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=462446"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=462446","title":{"rendered":"<span>\u0421\u043e\u0437\u0434\u0430\u0451\u043c \u0441\u0432\u043e\u0439 Telegram-\u043a\u043b\u043e\u043d \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Next.js \u0438 TailwindCSS \u2014 \u0427\u0430\u0441\u0442\u044c 1<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e28\/3ba\/cef\/e283bacefea2cb5f1ef8683b153784ca.jpg\" width=\"1700\" height=\"904\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/e28\/3ba\/cef\/e283bacefea2cb5f1ef8683b153784ca.jpg 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/e28\/3ba\/cef\/e283bacefea2cb5f1ef8683b153784ca.jpg 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0447\u0430\u0442-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043d\u0443\u043b\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439. \u041d\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u0441\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u0432\u044b \u0434\u0443\u043c\u0430\u0435\u0442\u0435.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u043c\u044b \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <a href=\"https:\/\/web.telegram.org\/\" rel=\"noopener noreferrer nofollow\">\u043a\u043b\u043e\u043d\u0430 \u0432\u0435\u0431-\u0432\u0435\u0440\u0441\u0438\u0438 Telegram<\/a> \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Next.js, TailwindCSS \u0438 Stream SDK. \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0430\u043a\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e TailwindCSS.<\/p>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/getstream.io\/chat\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">Stream React Chat SDK<\/a>. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u0438\u0434\u0435\u043e- \u0438 \u0430\u0443\u0434\u0438\u043e\u0432\u044b\u0437\u043e\u0432\u044b \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/getstream.io\/video\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">Stream React Video and Audio SDK<\/a>.<\/p>\n<p>\u041a \u043a\u043e\u043d\u0446\u0443 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u0443 \u0432\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0447\u0430\u0442-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0435.<\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p><a href=\"https:\/\/youtu.be\/I6EnQlVdMpc\" rel=\"noopener noreferrer nofollow\">https:\/\/youtu.be\/I6EnQlVdMpc<\/a><\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 <a href=\"https:\/\/telegram-clone-pink.vercel.app\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0434\u0435\u043c\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a> \u0438 \u043d\u0430\u0439\u0442\u0438 \u0435\u0433\u043e \u043a\u043e\u0434 \u0432 \u044d\u0442\u043e\u043c <a href=\"https:\/\/github.com\/TropicolX\/telegram-clone\" rel=\"noopener noreferrer nofollow\">GitHub-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<p>\u0427\u0442\u043e \u0436, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c!<\/p>\n<h2>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u043b\u044c\u0437\u0443 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u044b React:<\/strong> \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 React.<\/p>\n<\/li>\n<li>\n<p><strong>Node.js &amp; npm:<\/strong> \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b Node.js \u0438 npm, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u044b TypeScript, Next.js \u0438 TailwindCSS:<\/strong> \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u0438\u043c\u0435\u044f \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u043e \u043d\u0438\u0445, \u0432\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0433\u0447\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u044d\u0442\u043e\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435.<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u0435\u0441\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<pre><code class=\"javascript\">git clone https:\/\/github.com\/TropicolX\/telegram-clone.git cd telegram-clone git checkout starter npm install<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/90a\/871\/969\/90a87196912239fce2fb95e411340bfd.png\" width=\"388\" height=\"532\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/90a\/871\/969\/90a87196912239fce2fb95e411340bfd.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/90a\/871\/969\/90a87196912239fce2fb95e411340bfd.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u042d\u0442\u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0430\u0448 Next.js \u0441\u0435\u0442\u0430\u043f \u0441 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c\u0438 TypeScript \u0438 TailwindCSS. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0434\u0440\u0443\u0433\u0438\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435:<\/p>\n<ul>\n<li>\n<p><code>components<\/code>: \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p><code>hooks<\/code>: \u0412 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 React-\u0445\u0443\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><code>lib<\/code>: \u042d\u0442\u0430 \u043f\u0430\u043f\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0430\u0439\u043b<code> utils.ts<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Clerk<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Telegram Web, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u043e\u0439\u0442\u0438 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0442\u043e\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432 \u043d\u0430\u0448 \u043a\u043b\u043e\u043d \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e Clerk.<\/p>\n<h4>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Clerk?<\/h4>\n<p><a href=\"https:\/\/clerk.com\/\" rel=\"noopener noreferrer nofollow\">Clerk<\/a> \u2014 \u044d\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0448\u0438\u0440\u043e\u043a\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, API \u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0434\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<p>\u042d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 \u043d\u0430\u0448 Telegram-\u043a\u043b\u043e\u043d.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Clerk<\/h3>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7d2\/87c\/154\/7d287c15435a8a46486f7383a0bb8da9.png\" alt=\"Clerk sign-up page\" width=\"1600\" height=\"870\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/7d2\/87c\/154\/7d287c15435a8a46486f7383a0bb8da9.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/7d2\/87c\/154\/7d287c15435a8a46486f7383a0bb8da9.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Clerk sign-up page<\/figcaption><\/div>\n<\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 Clerk, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0438\u0445 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 <a href=\"https:\/\/dashboard.clerk.com\/sign-up\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 Clerk<\/a> \u0438 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0439\u0442\u0435\u0441\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0438\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Clerk<\/h3>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c34\/783\/6ea\/c347836ea96878e5d15f3c18274a5905.png\" width=\"1266\" height=\"724\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/c34\/783\/6ea\/c347836ea96878e5d15f3c18274a5905.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/c34\/783\/6ea\/c347836ea96878e5d15f3c18274a5905.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ol>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;<strong>Create application<\/strong>&#171;.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u043e\u0432\u0438\u0442\u0435 \u0441\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u201c<strong>Telegram clone<\/strong>\u201d.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u201c<strong>Sign in options<\/strong>\u201d \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 <strong>Email<\/strong>, <strong>Username<\/strong>, \u0438 <strong>Google<\/strong>.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;<strong>Create application<\/strong>&#171;, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d66\/6f6\/1c2\/d666f61c28d66b0fd71c525bfbe162d3.png\" alt=\"Clerk dashboard steps\" width=\"1600\" height=\"348\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/d66\/6f6\/1c2\/d666f61c28d66b0fd71c525bfbe162d3.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/d66\/6f6\/1c2\/d666f61c28d66b0fd71c525bfbe162d3.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Clerk dashboard steps<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d, \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043e\u0431\u0437\u043e\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0417\u0434\u0435\u0441\u044c \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0441\u0432\u043e\u0438 <strong>Publishable Key<\/strong> \u0438 <strong>Secret Key<\/strong> \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0438\u0445, \u043e\u043d\u0438 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0432\u0430\u043c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/82c\/073\/c8b\/82c073c8bba0289a4b441f8a85e8d571.png\" width=\"1600\" height=\"915\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/82c\/073\/c8b\/82c073c8bba0289a4b441f8a85e8d571.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/82c\/073\/c8b\/82c073c8bba0289a4b441f8a85e8d571.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0433 \u0432\u0432\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0438 \u0438\u043c\u044f \u0438 \u0444\u0430\u043c\u0438\u043b\u0438\u044e, \u043f\u043e\u0434\u043e\u0431\u043d\u043e \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 Telegram. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ol>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u00a0\u0432\u043a\u043b\u0430\u0434\u043a\u0443 <strong>&#171;Configure<\/strong>&#187; \u043d\u0430 \u0441\u0432\u043e\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0439\u0434\u0438\u0442\u0435 \u043e\u043f\u0446\u0438\u044e &#171;<strong>Name<\/strong>&#187; \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;<strong>Personal Information<\/strong>&#187; \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0435\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0437\u043d\u0430\u0447\u043e\u043a \u0448\u0435\u0441\u0442\u0435\u0440\u0435\u043d\u043a\u0438 \u0440\u044f\u0434\u043e\u043c \u0441 \u043f\u043e\u043b\u0435\u043c &#171;<strong>Name<\/strong>&#187; \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0435\u0433\u043e \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u201c<strong>Continue<\/strong>\u201d, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ol>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Clerk \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c Clerk \u0432 \u0432\u0430\u0448 <a href=\"http:\/\/next.js\" rel=\"noopener noreferrer nofollow\">Next.js<\/a> \u043f\u0440\u043e\u0435\u043a\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ol>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Next.js SDK Clerk, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<p><code>npm install @clerk\/nextjs<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 <code>.env.local<\/code>-\u0444\u0430\u0439\u043b \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b:<\/p>\n<\/li>\n<\/ol>\n<p><code>NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key<\/code><\/p>\n<p><code>\u00a0CLERK_SECRET_KEY=your_clerk_secret_key<\/code><\/p>\n<p>       \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u0435 <code>your_clerk_publishable_key<\/code> \u0438 <code>your_clerk_secret_key<\/code> \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0431\u0437\u043e\u0440\u0430 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Clerk.<\/p>\n<p>   3.\u0427\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438,                     \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u0448 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u0430\u043a\u0435\u0442 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>&lt;ClerkProvider \/&gt;<\/code> Clerk.\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>app\/layout.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"javascript\">import type { Metadata } from 'next'; \u00a0import { ClerkProvider } from '@clerk\/nextjs';  \u00a0...  \u00a0export default function RootLayout({ \u00a0\u00a0\u00a0children, \u00a0}: Readonly&lt;{ \u00a0\u00a0\u00a0children: React.ReactNode; \u00a0}&gt;) { \u00a0\u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0\u00a0&lt;ClerkProvider&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;html lang=\"en\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;body className=\"h-svh w-svw lg:h-screen lg:w-screen antialiased text-color-text select-none overflow-hidden\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{children} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/body&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/html&gt; \u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/ClerkProvider&gt; \u00a0\u00a0\u00a0); \u00a0}<\/code><\/pre>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043b\u043e\u0433\u0438\u043d\u0430<\/h3>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430\u0448\u0435\u0433\u043e Telegram-\u043a\u043b\u043e\u043d\u0430 \u0441\u0442\u0430\u043d\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043b\u043e\u0433\u0438\u043d\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Clerk <code>&lt;SignUp \/&gt;<\/code> \u0438 <code>&lt;SignIn \/&gt;<\/code>. \u042d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u0432 \u0441\u0435\u0431\u044f \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<p><strong>       1.\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438:<\/strong> \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Clerk <code>&lt;SignUp \/&gt;<\/code> \u0438 <code>&lt;SignIn \/&gt;<\/code> \u0442\u0440\u0435\u0431\u0443\u044e\u0442, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438, \u0433\u0434\u0435 \u043e\u043d\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0432 \u0432\u0430\u0448 <code>.env.local<\/code>-\u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"javascript\">NEXT_PUBLIC_CLERK_SIGN_IN_URL=\/sign-in \u00a0NEXT_PUBLIC_CLERK_SIGN_UP_URL=\/sign-up<\/code><\/pre>\n<p><strong>       2.\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438:<\/strong> \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>app\/sign-up\/[[...sign-up]]\/page.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">import { SignUp } from '@clerk\/nextjs';  \u00a0export default function Page() { \u00a0\u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"sm:w-svw sm:h-svh py-4 bg-background w-full h-full flex items-center justify-center\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;SignUp \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0); \u00a0}<\/code><\/pre>\n<p><strong>       3.\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u0445\u043e\u0434\u0430:<\/strong> \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>page.tsx<\/code> \u0432 \u043f\u0430\u043f\u043a\u0435 <code>app\/sign-in\/[[...sign-in]]<\/code> \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">import { SignIn } from '@clerk\/nextjs';  \u00a0export default function Page() { \u00a0\u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;div className=\"w-svw h-svh bg-background flex items-center justify-center\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;SignIn \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0); \u00a0}<\/code><\/pre>\n<p><strong>      4.\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 Clerk Middleware:<\/strong> \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 middleware \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432. \u041d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0437\u0430\u043a\u0440\u044b\u0432 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>src<\/code> \u0444\u0430\u0439\u043b<code> middleware.ts<\/code> \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">import { clerkMiddleware, createRouteMatcher } from '@clerk\/nextjs\/server';  \u00a0const isPublicRoute = createRouteMatcher(['\/sign-in(.*)', '\/sign-up(.*)']);  \u00a0export default clerkMiddleware(async (auth, request) =&gt; { \u00a0\u00a0\u00a0if (!isPublicRoute(request)) { \u00a0\u00a0\u00a0\u00a0\u00a0await auth.protect(); \u00a0\u00a0\u00a0} \u00a0});  \u00a0export const config = { \u00a0\u00a0\u00a0matcher: [ \u00a0\u00a0\u00a0\u00a0\u00a0\/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u044b Next.js \u0438 \u0432\u0441\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043f\u043e\u0438\u0441\u043a\u0430  \u00a0\u00a0\u00a0\u00a0\u00a0'\/((?!_next|[^?]*\\\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', \u00a0\u00a0\u00a0\u00a0\u00a0\/\/ \u0412\u0441\u0435\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 API \u00a0\u00a0\u00a0\u00a0\u00a0'\/(api|trpc)(.*)', \u00a0\u00a0\u00a0], \u00a0};<\/code><\/pre>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cea\/5e1\/a6f\/cea5e1a6f132bb27b7752389c7179c60.png\" width=\"1266\" height=\"724\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/cea\/5e1\/a6f\/cea5e1a6f132bb27b7752389c7179c60.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/cea\/5e1\/a6f\/cea5e1a6f132bb27b7752389c7179c60.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0448\u0430\u0433\u043e\u0432 Clerk \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0432 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u0432\u0445\u043e\u0434\u0430 \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Stream<\/h2>\n<h4>What is Stream?<\/h4>\n<h4>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Stream?<\/h4>\n<p><a href=\"https:\/\/getstream.io\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">Stream<\/a> \u2014 \u044d\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043b\u0435\u0433\u043a\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0447\u0430\u0442\u0430 \u0438 \u0432\u0438\u0434\u0435\u043e \u0432 \u0441\u0432\u043e\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u043d\u0443\u043b\u044f, Stream \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 API \u0438 SDK, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441.<\/p>\n<p>\u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/getstream.io\/video\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">React SDK for Video<\/a> \u0438 <a href=\"https:\/\/getstream.io\/chat\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">React Chat SDK<\/a> Stream \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0447\u0430\u0442\u0430 \u0438 \u0432\u0438\u0434\u0435\u043e\u0437\u0432\u043e\u043d\u043a\u043e\u0432 \u0432 \u043d\u0430\u0448\u0435\u043c Telegram-\u043a\u043b\u043e\u043d\u0435.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Stream<\/h3>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/189\/540\/c19\/189540c19da9d933ee744dc0e75ecc0c.png\" width=\"1600\" height=\"1009\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/189\/540\/c19\/189540c19da9d933ee744dc0e75ecc0c.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/189\/540\/c19\/189540c19da9d933ee744dc0e75ecc0c.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Stream:<\/p>\n<ol>\n<li>\n<p><strong>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f:<\/strong> \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 <a href=\"https:\/\/getstream.io\/accounts\/signup\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 Stream<\/a> \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0438\u043b\u0438 \u043b\u043e\u0433\u0438\u043d \u0432 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432\u0430\u0441 \u043f\u043e\u043f\u0440\u043e\u0441\u044f\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e \u0432\u0430\u0448\u0435\u043c \u0440\u043e\u0434\u0435 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043e\u0442\u0440\u0430\u0441\u043b\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u00a0\u043e\u043f\u0446\u0438\u0438 &#171;<strong>Chat Messaging<\/strong>&#187; \u0438 &#171;<strong>Video and Audio<\/strong>&#171;, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u044d\u0442\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ee1\/03c\/a78\/ee103ca786b1e29b131163b4e24ed57d.png\" alt=\"Strem sign up options\" width=\"576\" height=\"228\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/ee1\/03c\/a78\/ee103ca786b1e29b131163b4e24ed57d.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/ee1\/03c\/a78\/ee103ca786b1e29b131163b4e24ed57d.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/p>\n<div><figcaption>Strem sign up options<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<li>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;<strong>Complete Signup<\/strong>&#171;, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0448\u0430\u0433\u043e\u0432 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f Stream.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Stream<\/h2>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/600\/dc3\/d35\/600dc3d352801d6ae6aa398a69a4ab85.png\" width=\"1461\" height=\"848\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/600\/dc3\/d35\/600dc3d352801d6ae6aa398a69a4ab85.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/600\/dc3\/d35\/600dc3d352801d6ae6aa398a69a4ab85.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Stream-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<ol>\n<li>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/strong> \u0412 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443 \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f Stream \u043d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;Create App&#187;.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0441\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>App Name:<\/strong> \u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u0438\u043c\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#171;<strong>the-telegram-clone<\/strong>&#171;, \u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u044b\u0431\u043e\u0440\u0443.<\/p>\n<\/li>\n<li>\n<p><strong>Region:<\/strong> \u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043a \u0432\u0430\u043c \u0440\u0435\u0433\u0438\u043e\u043d.<\/p>\n<\/li>\n<li>\n<p><strong>Environment:<\/strong> \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0432 \u044d\u0442\u043e\u0439 \u043e\u043f\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#171;<strong>Development<\/strong>&#171;.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 &#171;<strong>Create App<\/strong>&#171;, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043a\u043b\u044e\u0447\u0438 API<\/strong>: \u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b &#171;<strong>App Access Keys<\/strong>&#171;. \u042d\u0442\u0438 \u043a\u043b\u044e\u0447\u0438 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0432\u0430\u043c \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f Stream \u043a \u0432\u0430\u0448\u0435\u043c\u0443 \u043f\u0440\u043e\u0435\u043a\u0442\u0443.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/208\/7ef\/84a\/2087ef84aa04386d645afccfb628de38.png\" width=\"1600\" height=\"336\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/208\/7ef\/84a\/2087ef84aa04386d645afccfb628de38.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/208\/7ef\/84a\/2087ef84aa04386d645afccfb628de38.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<\/li>\n<\/ol>\n<h4>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Stream SDK<\/h4>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c Stream \u0432 \u043d\u0430\u0448\u0435\u043c Next.js \u043f\u0440\u043e\u0435\u043a\u0442\u0435, \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u0438\u0442\u0441\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043f\u0430\u043a\u0435\u0442\u043e\u0432 SDK:<\/p>\n<p><strong>      1.\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0435 Stream SDK:<\/strong> \u0414\u043b\u044f \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0445 \u043f\u0430\u043a\u0435\u0442\u043e\u0432 \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<pre><code class=\"javascript\">npm install @stream-io\/node-sdk @stream-io\/video-react-sdk stream-chat-react stream-chat<\/code><\/pre>\n<p><strong>      2.\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043a\u043b\u044e\u0447\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f Stream:<\/strong> \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u043a\u043b\u044e\u0447\u0438 API Stream \u0432 \u0441\u0432\u043e\u0439 <code>.env.local<\/code>-\u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"javascript\">NEXT_PUBLIC_STREAM_API_KEY=your_stream_api_key \u00a0STREAM_API_SECRET=your_stream_api_secret<\/code><\/pre>\n<p>\u0417\u0430\u043c\u0435\u043d\u0438\u0442\u0435 <code>your_stream_api_key<\/code> \u0438 <code>your_stream_api_secret<\/code> \u043d\u0430 \u043a\u043b\u044e\u0447\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u043b\u0438 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;<strong>App Access Keys<\/strong>&#187; \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f Stream.<\/p>\n<p><strong>      3.\u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0441\u0442\u0438\u043b\u0435\u0439:<\/strong> \u041f\u0430\u043a\u0435\u0442\u044b Stream \u00a0<code>@stream-io\/video-react-sdk<\/code> and <code>stream-chat-react<\/code> \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 CSS \u0442\u0430\u0431\u043b\u0438\u0446\u044b \u0434\u043b\u044f \u0441\u0432\u043e\u0438\u0445 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043e\u0432. \u0418\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 CSS <code>@stream-io\/video-react-sdk<\/code> \u0432 \u0432\u0430\u0448 \u0444\u0430\u0439\u043b <code>app\/layout.tsx<\/code>:<a href=\"https:\/\/getstream.io\/video\/docs\/react\/ui-components\/video-theme\/#importing-the-css\" rel=\"noopener noreferrer nofollow\">\u200b<\/a><\/p>\n<pre><code class=\"javascript\">...\u00a0 \u00a0import '@stream-io\/video-react-sdk\/dist\/css\/styles.css'; \u00a0import '.\/globals.scss'; \u00a0...<\/code><\/pre>\n<p>\u0417\u0430\u0442\u0435\u043c \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0439\u0442\u0435 \u0441\u0442\u0438\u043b\u0438 <code>stream-chat-react<\/code> \u0432 \u0441\u0432\u043e\u0439 \u0444\u0430\u0439\u043b <code>globals.scss<\/code>:<\/p>\n<pre><code class=\"javascript\">... \u00a0@import \"~stream-chat-react\/dist\/scss\/v2\/index.scss\"; \u00a0...<\/code><\/pre>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0438\u0441\u0445\u043e\u0434\u043d\u043e\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430<\/h2>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/70c\/396\/5f9\/70c3965f931ed54a156ac12150dfceb0.png\" width=\"1072\" height=\"676\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/r\/w780\/getpro\/habr\/upload_files\/70c\/396\/5f9\/70c3965f931ed54a156ac12150dfceb0.png 780w,&#10;       https:\/\/habrastorage.org\/r\/w1560\/getpro\/habr\/upload_files\/70c\/396\/5f9\/70c3965f931ed54a156ac12150dfceb0.png 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0443\u0441\u043f\u0435\u0448\u043d\u043e\u0439 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0438 Clerk \u0438 Stream \u043c\u044b \u0433\u043e\u0442\u043e\u0432\u044b \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u0442\u044c \u043a \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044e \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043d\u0430\u0448\u0435\u0433\u043e Telegram-\u043a\u043b\u043e\u043d\u0430.<\/p>\n<p>\u041f\u0435\u0440\u0432\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u0441\u0442\u0430\u043d\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043e\u0431\u0449\u0435\u0433\u043e \u043c\u0430\u043a\u0435\u0442\u0430 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u042d\u0442\u043e\u0442 \u043c\u0430\u043a\u0435\u0442 \u0431\u0443\u0434\u0435\u0442 \u0432\u043a\u043b\u044e\u0447\u0430\u0442\u044c \u0432\u0441\u0435 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u0447\u0430\u0442\u0430 \u0438 \u0432\u0438\u0434\u0435\u043e\u0434\u0430\u043d\u043d\u044b\u0445 Stream \u0432\u043e \u0432\u0441\u0435\u043c \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u041d\u0430 \u043d\u0435\u043c \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0431\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c, \u043d\u0430 \u043a\u043e\u0442\u043e\u0440\u043e\u0439 \u043c\u044b \u0440\u0430\u0437\u043c\u0435\u0441\u0442\u0438\u043c \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0430\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<p>\u0414\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u043f\u0430\u043f\u043a\u0443 <code>a<\/code> \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>app<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0444\u0430\u0439\u043b <code>layout.tsx<\/code> \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<pre><code class=\"javascript\">'use client'; import { ReactNode, useEffect, useState } from 'react'; import { useParams } from 'next\/navigation'; import { useUser } from '@clerk\/nextjs'; import { StreamChat } from 'stream-chat'; import { Chat } from 'stream-chat-react'; import { StreamVideo, StreamVideoClient } from '@stream-io\/video-react-sdk'; import clsx from 'clsx';  interface LayoutProps { \u00a0\u00a0children?: ReactNode; }  const tokenProvider = async (userId: string) =&gt; { \u00a0\u00a0const response = await fetch('\/api\/token', { \u00a0\u00a0\u00a0\u00a0method: 'POST', \u00a0\u00a0\u00a0\u00a0headers: { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'Content-Type': 'application\/json', \u00a0\u00a0\u00a0\u00a0}, \u00a0\u00a0\u00a0\u00a0body: JSON.stringify({ userId: userId }), \u00a0\u00a0}); \u00a0\u00a0const data = await response.json(); \u00a0\u00a0return data.token; };  const API_KEY = process.env.NEXT_PUBLIC_STREAM_API_KEY as string; export const [minWidth, defaultWidth, defaultMaxWidth] = [256, 420, 424]; export default function Layout({ children }: LayoutProps) { \u00a0\u00a0const { user } = useUser(); \u00a0\u00a0const { channelId } = useParams&lt;{ channelId?: string }&gt;(); \u00a0\u00a0const [loading, setLoading] = useState(true); \u00a0\u00a0const [chatClient, setChatClient] = useState&lt;StreamChat&gt;(); \u00a0\u00a0const [videoClient, setVideoClient] = useState&lt;StreamVideoClient&gt;(); \u00a0\u00a0const [sidebarWidth, setSidebarWidth] = useState(0);  \u00a0\u00a0useEffect(() =&gt; { \u00a0\u00a0\u00a0\u00a0const savedWidth = \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0parseInt(localStorage.getItem('sidebarWidth') as string) || defaultWidth; \u00a0\u00a0\u00a0\u00a0localStorage.setItem('sidebarWidth', String(savedWidth)); \u00a0\u00a0\u00a0\u00a0setSidebarWidth(savedWidth); \u00a0\u00a0}, []);  \u00a0\u00a0useEffect(() =&gt; { \u00a0\u00a0\u00a0\u00a0const customProvider = async () =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const token = await tokenProvider(user!.id); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return token; \u00a0\u00a0\u00a0\u00a0};  \u00a0\u00a0\u00a0\u00a0const setUpChatAndVideo = async () =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const chatClient = StreamChat.getInstance(API_KEY); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const clerkUser = user!; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const chatUser = { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id: clerkUser.id, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: clerkUser.fullName!, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0image: clerkUser.hasImage ? clerkUser.imageUrl : undefined, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0custom: { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0username: clerkUser.username, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0};  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!chatClient.user) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0await chatClient.connectUser(chatUser, customProvider); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setChatClient(chatClient); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const videoClient = StreamVideoClient.getOrCreateInstance({ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0apiKey: API_KEY, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0user: chatUser, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0tokenProvider: customProvider, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setVideoClient(videoClient); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setLoading(false); \u00a0\u00a0\u00a0\u00a0};  \u00a0\u00a0\u00a0\u00a0if (user) setUpChatAndVideo(); \u00a0\u00a0}, [user, videoClient, chatClient]);  \u00a0\u00a0if (loading) \u00a0\u00a0\u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex h-full w-full\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0width: ${sidebarWidth || defaultWidth}px, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"bg-background h-full flex-shrink-0 relative\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt;&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative flex flex-col items-center w-full h-full overflow-hidden border-l border-solid border-l-color-borders\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"chat-background absolute top-0 left-0 w-full h-full -z-10 overflow-hidden bg-theme-background\"&gt;&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0); \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;Chat client={chatClient!}&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;StreamVideo client={videoClient!}&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex h-full w-full\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'fixed max-w-none left-0 right-0 top-0 bottom-0 lg:relative flex w-full h-full justify-center z-[1] min-w-0', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0!channelId &amp;&amp; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'translate-x-[100vw] min-[601px]:translate-x-[26.5rem] lg:translate-x-0' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative flex flex-col items-center w-full h-full overflow-hidden border-l border-solid border-l-color-borders\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"chat-background absolute top-0 left-0 w-full h-full -z-10 overflow-hidden bg-theme-background\"&gt;&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{children} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/StreamVideo&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/Chat&gt; \u00a0\u00a0); }<\/code><\/pre>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0444\u0430\u0439\u043b\u0435 \u043c\u043d\u043e\u0433\u043e \u0432\u0430\u0436\u043d\u044b\u0445 \u0432\u0435\u0449\u0435\u0439, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u0438\u0445 \u0432\u0441\u0435 \u043f\u043e \u043f\u043e\u0440\u044f\u0434\u043a\u0443:<\/p>\n<ul>\n<li>\n<p><strong>\u041f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a \u0442\u043e\u043a\u0435\u043d\u043e\u0432:<\/strong> \u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u044e <code>tokenProvider<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0442\u043e\u043a\u0435\u043d \u0438\u0437 \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 <code>\/api\/token<\/code>. \u042d\u0442\u043e\u0442 \u0442\u043e\u043a\u0435\u043d \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c \u0441\u0435\u0440\u0432\u0438\u0441\u0430\u043c Stream \u0434\u043b\u044f \u0438\u0434\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u0447\u0430\u0442\u0430 \u0438 \u0432\u0438\u0434\u0435\u043e:<\/strong> \u041c\u044b \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u043c <code>setUpChatAndVideo<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 <code>useEffect<\/code> \u0434\u043b\u044f \u043f\u043e\u0434\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043a \u0447\u0430\u0442- \u0438 \u0432\u0438\u0434\u0435\u043e-\u043a\u043b\u0438\u0435\u043d\u0442\u0443 Stream. \u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0434\u0430\u043d\u043d\u044b\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043e\u0442 Clerk \u0438 \u043f\u0435\u0440\u0435\u0434\u0430\u0435\u043c \u0438\u0445 \u043e\u0431\u043e\u0438\u043c \u043a\u043b\u0438\u0435\u043d\u0442\u0430\u043c \u0432\u043c\u0435\u0441\u0442\u0435 \u0441 \u0442\u043e\u043a\u0435\u043d\u043e\u043c \u043e\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u0441\u0442\u0430\u0432\u0449\u0438\u043a\u0430 \u0442\u043e\u043a\u0435\u043d\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p><strong>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0448\u0438\u0440\u0438\u043d\u043e\u0439 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438:<\/strong> \u041c\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u043c \u0448\u0438\u0440\u0438\u043d\u0443 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 (<code>sidebarWidth<\/code>) \u0432 <code>localStorage<\/code>. \u041a\u043e\u0433\u0434\u0430 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u0442\u0441\u044f, \u043c\u044b \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u044d\u0442\u043e \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u0431\u044b \u0431\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c \u0432\u0441\u0435\u0433\u0434\u0430 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b\u0430 \u0437\u0430\u0434\u0430\u043d\u043d\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u043c \u0440\u0430\u0437\u043c\u0435\u0440\u0443.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u0449\u0438\u0439 \u043c\u0430\u043a\u0435\u0442:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043c\u044b \u0432\u0441\u0435 \u0435\u0449\u0435 \u0437\u0430\u0433\u0440\u0443\u0436\u0430\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0438\u043b\u0438 \u0447\u0442\u043e-\u0442\u043e \u043c\u043e\u043d\u0442\u0438\u0440\u0443\u0435\u043c, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u043c\u0430\u043a\u0435\u0442-\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c.<\/p>\n<\/li>\n<li>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u0432\u0441\u0435 \u0431\u0443\u0434\u0435\u0442 \u0433\u043e\u0442\u043e\u0432\u043e, \u043c\u044b \u043e\u0431\u043e\u0440\u0430\u0447\u0438\u0432\u0430\u0435\u043c \u0432\u0441\u0435 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b <code>&lt;Chat&gt;<\/code> \u0438 <code>&lt;StreamVideo&gt;<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0411\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c (\u043b\u0435\u0432\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0441\u043e\u0431\u043e\u0439 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u044b\u0439 \u0440\u0430\u0437\u0434\u0435\u043b, \u0438 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0435 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u043e\u0435 (\u043f\u0440\u0430\u0432\u0430\u044f \u043e\u0431\u043b\u0430\u0441\u0442\u044c), \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0447\u0430\u0442, \u043f\u0435\u0440\u0435\u0434\u0430\u044e\u0442\u0441\u044f \u043c\u0430\u043a\u0435\u0442\u0443 \u0432 \u043a\u0430\u0447\u0435\u0441\u0442\u0432\u0435 \u0434\u043e\u0447\u0435\u0440\u043d\u0438\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0430 API \u0434\u043b\u044f \u0442\u043e\u043a\u0435\u043d\u0430\u00a0<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0430\u0440\u0448\u0440\u0443\u0442 \u0434\u043b\u044f \u043a\u043e\u043d\u0435\u0447\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u0438 \/api\/token, \u043a\u043e\u0442\u043e\u0440\u0443\u044e \u043c\u044b \u0443\u0436\u0435 \u0443\u043f\u043e\u043c\u0438\u043d\u0430\u043b\u0438 \u0440\u0430\u043d\u0435\u0435.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 app \u043f\u0430\u043f\u043a\u0443 \/api\/token, \u0430 \u0437\u0430\u0442\u0435\u043c \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0444\u0430\u0439\u043b route.ts \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u043c\u044b\u043c:<\/p>\n<pre><code class=\"javascript\">import { StreamClient } from '@stream-io\/node-sdk';  const API_KEY = process.env.NEXT_PUBLIC_STREAM_API_KEY!; const SECRET = process.env.STREAM_API_SECRET!;  export async function POST(request: Request) { \u00a0\u00a0const client = new StreamClient(API_KEY, SECRET);  \u00a0\u00a0const body = await request.json();  \u00a0\u00a0const userId = body?.userId;  \u00a0\u00a0if (!userId) { \u00a0\u00a0\u00a0\u00a0return Response.error(); \u00a0\u00a0}  \u00a0\u00a0const token = client.generateUserToken({ user_id: userId });  \u00a0\u00a0const response = { \u00a0\u00a0\u00a0\u00a0userId: userId, \u00a0\u00a0\u00a0\u00a0token: token, \u00a0\u00a0};  \u00a0\u00a0return Response.json(response); }<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u0434 \u043e\u0442\u0432\u0435\u0447\u0430\u0435\u0442 \u0437\u0430 \u0433\u0435\u043d\u0435\u0440\u0430\u0446\u0438\u044e \u0438 \u0432\u043e\u0437\u0432\u0440\u0430\u0442 \u0442\u043e\u043a\u0435\u043d\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u043d\u043e\u0433\u043e <code>userId<\/code>.<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043a\u0430\u043d\u0430\u043b\u043e\u0432<\/h2>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u0447\u0430\u0442 \u0432 \u043d\u0430\u0448\u0435\u043c Telegram-\u043a\u043b\u043e\u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u0432 \u0440\u0430\u043c\u043a\u0430\u0445 \u043e\u0442\u0434\u0435\u043b\u044c\u043d\u043e\u0433\u043e \u043a\u0430\u043d\u0430\u043b\u0430. \u0412 Stream \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f:<\/p>\n<ul>\n<li>\n<p>\u0421\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043a\u043e\u0442\u043e\u0440\u044b\u043c\u0438 \u043e\u0431\u043c\u0435\u043d\u0438\u0432\u0430\u044e\u0442\u0441\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u043b\u044e\u0434\u0435\u0439, \u0441\u043b\u0435\u0434\u044f\u0449\u0438\u0445 \u0437\u0430 \u043a\u0430\u043d\u0430\u043b\u043e\u043c (\u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0445 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432).<\/p>\n<\/li>\n<li>\n<p>\u041e\u043f\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u0441\u043f\u0438\u0441\u043e\u043a \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 (\u0434\u043b\u044f \u043b\u0438\u0447\u043d\u044b\u0445 \u0431\u0435\u0441\u0435\u0434).<\/p>\n<\/li>\n<\/ul>\n<p>\u041f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0438\u043c\u0435\u0435\u0442 \u0443\u043d\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0439 ID, \u043d\u0430\u0448\u0435\u0439 \u0433\u043b\u0430\u0432\u043d\u043e\u0439 \u0442\u043e\u0447\u043a\u043e\u0439 \u0432\u0445\u043e\u0434\u0430 \u0441\u0442\u0430\u043d\u0435\u0442 \u043c\u0430\u0440\u0448\u0440\u0443\u0442 <code>\/a\/[channelId]<\/code>, \u043f\u043e \u043a\u043e\u0442\u043e\u0440\u043e\u043c\u0443 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0431\u0443\u0434\u0443\u0442 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u043e\u0432\u0430\u0442\u044c \u0441 \u0447\u0430\u0442\u043e\u043c. \u041e\u0434\u043d\u0430\u043a\u043e \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u043f\u043e\u0441\u0435\u0449\u0435\u043d\u0438\u0435 \/ \u043d\u0435 \u043f\u0440\u0438\u0432\u043e\u0434\u0438\u0442 \u043d\u0430 \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u043f\u043e\u0437\u0430\u0431\u043e\u0442\u0438\u0442\u044c\u0441\u044f \u043e \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u043d\u0443\u0436\u043d\u043e\u0435 \u043c\u0435\u0441\u0442\u043e.<\/p>\n<p>\u0421\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438 \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438 \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<ol>\n<li>\n<p>\u041c\u044b \u0431\u0443\u0434\u0435\u043c \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0438\u0437 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b (<code>\/<\/code>) \u0432 <code>\/a<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0443 \u0432 \/a \u0438\u0437 \u0441\u043e\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0439 \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0441\u0442\u0440\u043e\u0438\u043c <code>\/a\/[channelId]<\/code>, \u0433\u0434\u0435 \u0438 \u0431\u0443\u0434\u0435\u0442 \u0440\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0442\u044c\u0441\u044f \u0447\u0430\u0442.<\/p>\n<\/li>\n<\/ol>\n<h3>\u041f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u0439 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b<\/h3>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0432\u0441\u0435\u0433\u043e, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434 \u0432 \u0444\u0430\u0439\u043b <code>\/app\/page.tsx<\/code>:<\/p>\n<pre><code class=\"javascript\">import { redirect } from 'next\/navigation';  export default function Home() { \u00a0\u00a0redirect('\/a'); }<\/code><\/pre>\n<p>\u0422\u0430\u043a\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c \u043f\u0440\u0438 \u043f\u043e\u0441\u0435\u0449\u0435\u043d\u0438\u0438 <code>\/<\/code> \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u044e\u0442\u0441\u044f \u043d\u0430 <code>\/a<\/code>, \u0433\u0434\u0435 \u0431\u0443\u0434\u0443\u0442 \u043e\u0431\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c\u0441\u044f \u043d\u0430\u0448\u0438 \u043a\u0430\u043d\u0430\u043b\u044b.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b-\u0437\u0430\u0433\u043b\u0443\u0448\u043a\u0438<\/h3>\n<p>\u0417\u0430\u0442\u0435\u043c \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>page.tsx<\/code> \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 <code>\/app\/a\/<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">const Main = () =&gt; { \u00a0\u00a0return null; };  export default Main;<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043d\u0435 \u0431\u0443\u0434\u0435\u0442 \u043d\u0438\u0447\u0435\u0433\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c, \u043e\u043d \u043f\u0440\u043e\u0441\u0442\u043e \u0441\u043b\u0443\u0436\u0438\u0442 \u0437\u0430\u0433\u043b\u0443\u0448\u043a\u043e\u0439 \u0434\u043b\u044f \u043f\u043e\u0434\u0434\u0435\u0440\u0436\u0430\u043d\u0438\u044f \u0447\u0438\u0441\u0442\u043e\u0442\u044b \u043d\u0430\u0448\u0435\u0439 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u044b \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u0438.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043a\u0430\u043d\u0430\u043b\u0430<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0433\u043b\u0430\u0432\u043d\u0443\u044e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0447\u0430\u0442\u0430. \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 <code>\/app\/a\/<\/code> \u043f\u0430\u043f\u043a\u0443 \u0441 \u0438\u043c\u0435\u043d\u0435\u043c <code>[channelId]<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0444\u0430\u0439\u043b <code>page.tsx<\/code> \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">'use client';  import { useParams } from 'next\/navigation';  const Chat = () =&gt; { \u00a0\u00a0const { channelId } = useParams&lt;{ channelId: string }&gt;(); \u00a0\u00a0return &lt;div&gt;{channelId}&lt;\/div&gt;; };  export default Chat;<\/code><\/pre>\n<p>\u042d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 <code>channelId<\/code> \u0438\u0437 URL \u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0435\u0433\u043e. \u041f\u043e\u0437\u0436\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u043e\u0442 ID \u0434\u043b\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445 \u0447\u0430\u0442\u0430 \u0438\u0437 Stream.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e73\/a07\/774\/e73a077743f35f67a3a03a1e081ffcbc.gif\" width=\"1100\" height=\"699\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e73\/a07\/774\/e73a077743f35f67a3a03a1e081ffcbc.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/e73\/a07\/774\/e73a077743f35f67a3a03a1e081ffcbc.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0411\u043b\u0430\u0433\u043e\u0434\u0430\u0440\u044f \u044d\u0442\u043e\u043c\u0443 \u0441\u0435\u0442\u0430\u043f\u0443 \u043d\u0430\u0448\u0430 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u0438\u0437\u0430\u0446\u0438\u044f \u0442\u0435\u043f\u0435\u0440\u044c \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u0430 \u0434\u043e\u043b\u0436\u043d\u044b\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c.<\/p>\n<h2>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0441\u043f\u0438\u0441\u043a\u0430 \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u043d\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u043c \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438. \u0411\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0440\u043e\u0441\u043c\u0430\u0442\u0440\u0438\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0430\u043a\u0442\u0438\u0432\u043d\u044b\u0435 \u0447\u0430\u0442\u044b, \u0438\u0441\u043a\u0430\u0442\u044c \u0440\u0430\u0437\u0433\u043e\u0432\u043e\u0440\u044b \u0438 \u0438\u043d\u0438\u0446\u0438\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435. \u0414\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u044d\u0442\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0438 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 Stream <a href=\"https:\/\/getstream.io\/chat\/docs\/sdk\/react\/components\/core-components\/channel_list\/\" rel=\"noopener noreferrer nofollow\"><code>channelList<\/code><\/a>. \u041c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0435\u0433\u043e \u0441\u0442\u0438\u043b\u044c \u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438, \u0447\u0442\u043e\u0431\u044b \u043e\u043d \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u043e \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u043e\u0432\u0430\u043b Telegram.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u043f\u0430\u043f\u043a\u0438 \u0441 \u0447\u0430\u0442\u0430\u043c\u0438<\/h3>\n<p>\u041f\u0435\u0440\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0439 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438, \u2014 \u044d\u0442\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>ChatFolders<\/code>. \u042d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c <code>ChannelList<\/code>, \u0441\u0442\u0440\u043e\u043a\u0443 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u043c\u0435\u043d\u044e \u043f\u0440\u043e\u0444\u0438\u043b\u044f Clerk \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>components<\/code> \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>ChatFolders.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">import { useRouter } from 'next\/navigation'; import { useUser } from '@clerk\/nextjs'; import { \u00a0\u00a0ChannelList, \u00a0\u00a0ChannelSearchProps, \u00a0\u00a0useChatContext, } from 'stream-chat-react';  import ChatPreview from '.\/ChatPreview'; import SearchBar from '.\/SearchBar'; import Spinner from '.\/Spinner';  const ChatFolders = ({}: ChannelSearchProps) =&gt; { \u00a0\u00a0const { user } = useUser(); \u00a0\u00a0const { client } = useChatContext(); \u00a0\u00a0const router = useRouter();  \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex-1 overflow-hidden relative w-full h-[calc(100%-3.5rem)]\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex flex-col w-full h-full overflow-hidden\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex-1 overflow-hidden relative w-full h-full\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"w-full h-full\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"custom-scroll p-2 overflow-y-scroll overflow-x-hidden h-full bg-background pe-2 min-[820px]:pe-[0px]\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;ChannelList \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Preview={ChatPreview} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0sort={{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0last_message_at: -1, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0filters={{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0members: { $in: [client.userID!] }, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0showChannelSearch \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0additionalChannelSearchProps={{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0searchForChannels: true, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onSelectResult: async (_, result) =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (result.cid) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0router.push(\/a\/${result.id}); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const channel = client.getChannelByMembers('messaging', { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0members: [user!.id, result.id!], \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0await channel.create(); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0router.push(\/a\/${channel.data?.id}); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0SearchBar: SearchBar, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0LoadingIndicator={() =&gt; ( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"w-full h-full flex items-center justify-center\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative w-12 h-12\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Spinner color=\"var(--color-primary)\" \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0); };  export default ChatFolders;<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0437\u0431\u0435\u0440\u0435\u043c \u043d\u0435\u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u043c\u043e\u043c\u0435\u043d\u0442\u044b \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/p>\n<ul>\n<li>\n<p><strong>\u041a\u043e\u043d\u0442\u0435\u043a\u0441\u0442 \u0447\u0430\u0442\u0430 \u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f (<code>user<\/code>) \u0438\u0437 Clerk \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>useUser()<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>client<\/code> \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442\u0441\u044f \u0438\u0437 <code>useChatContext()<\/code>, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u044f\u043c \u0447\u0430\u0442\u0430 Stream.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0421\u043f\u0438\u0441\u043e\u043a \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0438 \u043f\u043e\u0438\u0441\u043a:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c <code>ChannelList<\/code> \u0438\u0437 Stream \u0434\u043b\u044f \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u044f \u043a\u0430\u043d\u0430\u043b\u043e\u0432 \u0447\u0430\u0442\u043e\u0432 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f, \u043e\u0442\u0441\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0445 \u043f\u043e \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u043c\u0443 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u043b\u0438\u0441\u044c \u0442\u043e\u043b\u044c\u043a\u043e \u0442\u0435 \u043a\u0430\u043d\u0430\u043b\u044b, \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u043c \u043a\u043e\u0442\u043e\u0440\u044b\u0445 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043c\u044b \u043f\u0440\u0438\u043c\u0435\u043d\u044f\u0435\u043c \u0444\u0438\u043b\u044c\u0442\u0440 (<code>members: { $in: [client.userId!] }<\/code>).<\/p>\n<\/li>\n<li>\n<p>\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0438\u0441\u043a\u0430 (<code>SearchBar<\/code>) \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0438\u0441\u043a\u0430\u0442\u044c \u043a\u0430\u043d\u0430\u043b\u044b \u0438 \u0434\u0440\u0443\u0433\u0438\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0412\u044b\u0431\u043e\u0440 \u0438\u043b\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0447\u0430\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u043c \u043f\u043e\u0438\u0441\u043a\u0430 \u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043a\u0430\u043d\u0430\u043b (<code>cid<\/code> \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442), \u043c\u044b \u043f\u0435\u0440\u0435\u0445\u043e\u0434\u0438\u043c \u043a \u043d\u0435\u043c\u0443.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435, \u0435\u0441\u043b\u0438 \u044d\u0442\u043e \u0434\u0440\u0443\u0433\u043e\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c, \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0435\u043c \u0441 \u043d\u0438\u043c \u043d\u043e\u0432\u044b\u0439 \u0447\u0430\u0442 \u043e\u0434\u0438\u043d \u043d\u0430 \u043e\u0434\u0438\u043d, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <code>getChannelByMembers<\/code>, \u0430 \u0437\u0430\u0442\u0435\u043c \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0432 \u043d\u043e\u0432\u044b\u0439 \u0447\u0430\u0442.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0418\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438:<\/strong> \u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043c\u044b \u043f\u043e\u043a\u0430\u0437\u044b\u0432\u0430\u0435\u043c \u043e\u0442\u0446\u0435\u043d\u0442\u0440\u0438\u0440\u043e\u0432\u0430\u043d\u043d\u044b\u0439 <code>Spinner<\/code> \u0432 \u043e\u0431\u043b\u0430\u0441\u0442\u0438 \u0441\u043f\u0438\u0441\u043a\u0430 \u0447\u0430\u0442\u043e\u0432.<\/p>\n<\/li>\n<\/ul>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b <code>ChatPreview<\/code> \u0438 <code>Searchbar<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0443\u0436\u0435 \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u043e\u0432\u0430\u043b\u0438 \u0432 \u043d\u0430\u0448 \u043a\u043e\u0434.<\/p>\n<h3>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u043f\u0440\u0435\u0432\u044c\u044e \u0447\u0430\u0442\u043e\u0432<\/h3>\n<p>\u041a\u0430\u0436\u0434\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u043d\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0434\u043e\u043b\u0436\u0435\u043d \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0442\u044c \u043f\u0440\u0435\u0432\u044c\u044e, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0435\u0435 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0447\u0430\u0442\u0430, \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435, \u0432\u0440\u0435\u043c\u044f \u0438 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0445 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0439. \u041c\u044b \u0440\u0435\u0430\u043b\u0438\u0437\u0443\u0435\u043c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 <code>ChatPreview<\/code>.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>components<\/code> \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c <code>ChatPreview.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">import { useCallback, useMemo } from 'react'; import { usePathname, useRouter } from 'next\/navigation'; import { \u00a0\u00a0ChannelPreviewUIComponentProps, \u00a0\u00a0useChatContext, } from 'stream-chat-react'; import clsx from 'clsx';  import Avatar from '.\/Avatar';  const ChatPreview = ({ \u00a0\u00a0channel, \u00a0\u00a0displayTitle, \u00a0\u00a0unread, \u00a0\u00a0displayImage, \u00a0\u00a0lastMessage, }: ChannelPreviewUIComponentProps) =&gt; { \u00a0\u00a0const { client } = useChatContext(); \u00a0\u00a0const router = useRouter(); \u00a0\u00a0const pathname = usePathname();  \u00a0\u00a0const isDMChannel = channel.id?.startsWith('!members'); \u00a0\u00a0const goToChat = () =&gt; { \u00a0\u00a0\u00a0\u00a0const channelId = channel.id; \u00a0\u00a0\u00a0\u00a0router.push(\/a\/${channelId}); \u00a0\u00a0};  \u00a0\u00a0const getDMUser = useCallback(() =&gt; { \u00a0\u00a0\u00a0\u00a0const members = { ...channel.state.members }; \u00a0\u00a0\u00a0\u00a0delete members[client.userID!]; \u00a0\u00a0\u00a0\u00a0return Object.values(members)[0].user!; \u00a0\u00a0}, [channel.state.members, client.userID]);  \u00a0\u00a0const getChatName = useCallback(() =&gt; { \u00a0\u00a0\u00a0\u00a0if (displayTitle) return displayTitle; \u00a0\u00a0\u00a0\u00a0else { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const member = getDMUser(); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return member.name || ${member.first_name} ${member.last_name}; \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0}, [displayTitle, getDMUser]);  \u00a0\u00a0const getImage = useCallback(() =&gt; { \u00a0\u00a0\u00a0\u00a0if (displayImage) return displayImage; \u00a0\u00a0\u00a0\u00a0else if (isDMChannel) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const member = getDMUser(); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return member.image; \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0}, [displayImage, getDMUser, isDMChannel]);  \u00a0\u00a0const lastText = useMemo(() =&gt; { \u00a0\u00a0\u00a0\u00a0if (lastMessage) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return lastMessage.text; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0if (isDMChannel) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return ${getChatName()} joined Telegram; \u00a0\u00a0\u00a0\u00a0} else { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return `${ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ @ts-expect-error one of these will be defined \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0channel.data?.created_by?.first_name || \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ @ts-expect-error one of these will be defined \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0channel.data?.created_by?.name.split(' ')[0] \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} created the group \"${displayTitle}\"`; \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0}, [ \u00a0\u00a0\u00a0\u00a0lastMessage, \u00a0\u00a0\u00a0\u00a0channel.data?.created_by, \u00a0\u00a0\u00a0\u00a0getChatName, \u00a0\u00a0\u00a0\u00a0displayTitle, \u00a0\u00a0\u00a0\u00a0isDMChannel, \u00a0\u00a0]); \u00a0\u00a0const lastMessageDate = useMemo(() =&gt; { \u00a0\u00a0\u00a0\u00a0const date = new Date( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0lastMessage?.created_at || (channel.data?.created_at as string) \u00a0\u00a0\u00a0\u00a0); \u00a0\u00a0\u00a0\u00a0const today = new Date(); \u00a0\u00a0\u00a0\u00a0if ( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0date.getDate() === today.getDate() &amp;&amp; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0date.getMonth() === today.getMonth() &amp;&amp; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0date.getFullYear() === today.getFullYear() \u00a0\u00a0\u00a0\u00a0) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return date.toLocaleTimeString('en-US', { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0hour: 'numeric', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0minute: 'numeric', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0hour12: false, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0\u00a0\u00a0} else if (date.getFullYear() === today.getFullYear()) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return date.toLocaleDateString('en-US', { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0month: 'short', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0day: 'numeric', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0\u00a0\u00a0} else { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return date.toLocaleDateString('en-US', { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0month: 'short', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0day: 'numeric', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0year: 'numeric', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0}, [lastMessage, channel.data?.created_at]);  \u00a0\u00a0const active = useMemo(() =&gt; { \u00a0\u00a0\u00a0\u00a0const pathChannelId = pathname.split('\/').filter(Boolean).pop(); \u00a0\u00a0\u00a0\u00a0return pathChannelId === channel.id; \u00a0\u00a0}, [pathname, channel.id]);  \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'relative p-[.5625rem] cursor-pointer min-h-auto overflow-hidden flex items-center rounded-xl whitespace-nowrap gap-2', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0active &amp;&amp; 'bg-chat-active text-white', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0!active &amp;&amp; 'bg-background text-color-text hover:bg-chat-hover' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={goToChat} \u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Avatar \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data={{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: getChatName(), \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0image: getImage(), \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0width={54} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex-1 overflow-hidden\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex items-center justify-start overflow-hidden\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex items-center justify-start overflow-hidden gap-1\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h3 className=\"font-semibold truncate text-base\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{getChatName()} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/h3&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"grow min-w-2\" \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex items-center shrink-0 mr-[.1875rem] text-[.75rem]\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span className={active ? 'text-white' : 'text-color-text-meta'}&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{lastMessageDate} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/span&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex items-center justify-start truncate\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'truncate text-[.9375rem] text-left pr-1 grow', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0active &amp;&amp; 'text-white', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0!active &amp;&amp; 'text-color-text-secondary' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{lastText} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/p&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{unread !== undefined &amp;&amp; unread &gt; 0 &amp;&amp; ( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'min-w-6 h-6 shrink-0 rounded-xl text-sm leading-6 text-center py-0 px-[.4375rem] font-medium', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0active &amp;&amp; 'bg-white text-primary', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0!active &amp;&amp; 'bg-green text-white' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span className=\"inline-flex whitespace-pre\"&gt;{unread}&lt;\/span&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0); };  export default ChatPreview;<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043a\u043e\u0434\u0435:<\/p>\n<ul>\n<li>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u0438 \u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435 \u0438 \u0447\u0430\u0442\u0435:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041c\u044b \u043f\u043e\u043b\u0443\u0447\u0430\u0435\u043c \u0447\u0430\u0442-\u043a\u043b\u0438\u0435\u043d\u0442 (<code>client<\/code>) \u0441\u043c\u043e\u043c\u043e\u0449\u044c\u044e \u0445\u0443\u043a\u0430 <code>useChatContext()<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>getDMUser()<\/code> \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u044f\u0435\u0442 \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430 \u0432 \u043b\u0438\u0447\u043d\u043e\u043c \u0447\u0430\u0442\u0435, \u043d\u0435 \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e \u043e \u0447\u0430\u0442\u0435:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>getChatName()<\/code> \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u043c\u043e\u0435 \u0438\u043c\u044f \u0434\u043b\u044f \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u044b\u0445 \u0447\u0430\u0442\u043e\u0432 \u0438\u043b\u0438 \u0438\u043c\u044f \u0434\u0440\u0443\u0433\u043e\u0433\u043e \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0430 \u0434\u043b\u044f \u043b\u0438\u0447\u043d\u044b\u0445 \u0447\u0430\u0442\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>getImage()<\/code> \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0430\u0432\u0430\u0442\u0430\u0440 \u0447\u0430\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0424\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u043f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f \u0438 \u0432\u0440\u0435\u043c\u0435\u043d\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435\u0434\u043d\u0435\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f, \u0435\u0441\u043b\u0438 \u043e\u043d\u043e \u0441\u0443\u0449\u0435\u0441\u0442\u0432\u0443\u0435\u0442. \u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0434\u0435\u0444\u043e\u043b\u0442\u043d\u043e\u0435 \u0441\u0438\u0441\u0442\u0435\u043c\u043d\u043e\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 (\u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u201c\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043f\u0440\u0438\u0441\u043e\u0435\u0434\u0438\u043d\u0438\u043b\u0441\u044f \u043a Telegram\u201d \u0438\u043b\u0438 \u201c\u0413\u0440\u0443\u043f\u043f\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0430\u201d).<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>lastMessageDate<\/code> \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0432\u0430\u0435\u0442 \u043a\u043e\u0440\u0440\u0435\u043a\u0442\u043d\u043e\u0435 \u0444\u043e\u0440\u043c\u0430\u0442\u0438\u0440\u043e\u0432\u0430\u043d\u0438\u0435 \u0432\u0440\u0435\u043c\u0435\u043d\u0438:<\/p>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u0435 \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0441\u0435\u0433\u043e\u0434\u043d\u044f, \u043e\u043d\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0444\u043e\u0440\u043c\u0430\u0442\u0435 <code>HH:MM<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043e\u043d\u043e \u0431\u044b\u043b\u043e \u043e\u0442\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u043e \u0432 \u0442\u0435\u0447\u0435\u043d\u0438\u0435 \u044d\u0442\u043e\u0433\u043e \u0433\u043e\u0434\u0430, \u0442\u043e \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0441\u044f\u0446 \u0438 \u0434\u0430\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u043f\u0440\u043e\u0442\u0438\u0432\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0442\u043e\u043b\u044c\u043a\u043e \u0433\u043e\u0434.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u0435\u0440\u0435\u0445\u043e\u0434 \u043a \u0447\u0430\u0442\u0430\u043c:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u0447\u0430\u0442, \u043e\u043d \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043d\u0430 \u043d\u0435\u0433\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>router.push()<\/code>.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0412\u044b\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u0447\u0430\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0442\u0435\u043a\u0443\u0449\u0438\u0439 \u0447\u0430\u0442 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0443\u0435\u0442 \u0443\u043a\u0430\u0437\u0430\u043d\u043d\u043e\u043c\u0443 URL, \u043f\u0440\u0435\u0432\u044c\u044e \u0447\u0430\u0442\u0430 \u043f\u043e\u0434\u0441\u0432\u0435\u0447\u0438\u0432\u0430\u0435\u0442\u0441\u044f, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c, \u0447\u0442\u043e \u043e\u043d \u0430\u043a\u0442\u0438\u0432\u0435\u043d.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u0432 \u0447\u0430\u0442\u0435 \u0435\u0441\u0442\u044c \u043d\u0435\u043f\u0440\u043e\u0447\u0438\u0442\u0430\u043d\u043d\u044b\u0435 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0437\u0435\u043b\u0435\u043d\u044b\u0439 \u0437\u043d\u0430\u0447\u043e\u043a \u0441 \u0438\u0445 \u043a\u043e\u043b\u0438\u0447\u0435\u0441\u0442\u0432\u043e\u043c.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u043f\u0430\u043d\u0435\u043b\u0438 \u043f\u043e\u0438\u0441\u043a\u0430<\/h3>\n<p>\u041f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u0432\u044b\u043f\u043e\u043b\u043d\u044f\u0442\u044c \u043f\u043e\u0438\u0441\u043a \u0447\u0430\u0442\u043e\u0432 \u0438 \u043a\u0430\u043d\u0430\u043b\u043e\u0432. \u041e\u043d\u0430 \u0442\u0430\u043a\u0436\u0435 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c \u043c\u0435\u043d\u044e \u043f\u0440\u043e\u0444\u0438\u043b\u044f \u0434\u043b\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432\u043d\u0443\u0442\u0440\u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 <code>components<\/code> \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c <code>SearchBar.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">import { UserButton, useUser } from '@clerk\/nextjs'; import { SearchBarProps } from 'stream-chat-react';  import RippleButton from '.\/RippleButton';  const SearchBar = ({ exitSearch, onSearch, query }: SearchBarProps) =&gt; { \u00a0\u00a0const { user } = useUser();  \u00a0\u00a0const handleClick = () =&gt; { \u00a0\u00a0\u00a0\u00a0if (query) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0exitSearch(); \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0};  \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex items-center bg-background px-[.8125rem] pt-1.5 pb-2 gap-[.625rem] h-[56px]\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative h-10 w-10 [&amp;&gt;div:first-child]\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"[&amp;&gt;div]:opacity-0\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{user &amp;&amp; !query &amp;&amp; &lt;UserButton \/&gt;} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"absolute left-0 top-0 flex items-center justify-center pointer-events-none\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;RippleButton \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={handleClick} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0icon={query ? 'arrow-left' : 'menu'} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative w-full bg-chat-hover text-[rgba(var(--color-text-secondary-rgb),0.5)] max-w-[calc(100%-3.25rem)] border-[2px] border-chat-hover has-[:focus]:border-primary has-[:focus]:bg-background rounded-[1.375rem] flex items-center pe-[.1875rem] transition-opacity ease-[cubic-bezier(0.33,1,0.68,1)] duration-[330ms]\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"text\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name=\"Search\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={query} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={onSearch} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0placeholder=\"Search\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0autoComplete=\"off\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"peer order-2 h-10 text-black rounded-[1.375rem] bg-transparent pl-[11px] pt-[6px] pb-[7px] pr-[9px] focus:outline-none focus:caret-primary\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"w-6 h-6 ms-3 shrink-0 flex items-center justify-center peer-focus:text-primary\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;i className=\"icon icon-search text-2xl leading-[1]\" \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0); };  export default SearchBar;<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u044d\u0442\u043e\u0442 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442:<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0438 \u043a\u043d\u043e\u043f\u043a\u0430 \u043c\u0435\u043d\u044e:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0430\u0432\u0442\u043e\u0440\u0438\u0437\u043e\u0432\u0430\u043d \u0438 \u043f\u043e\u0438\u0441\u043a\u043e\u0432\u044b\u0439 \u0437\u0430\u043f\u0440\u043e\u0441 \u043e\u0442\u0441\u0443\u0442\u0441\u0442\u0432\u0443\u0435\u0442, \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u043a\u043d\u043e\u043f\u043a\u0430 Clerk <code>UserButton<\/code>.<\/p>\n<\/li>\n<li>\n<p><code>RippleButton<\/code> \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u043f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043c\u0435\u0436\u0434\u0443 \u0438\u043a\u043e\u043d\u043a\u043e\u0439 \u043c\u0435\u043d\u044e \u0438 \u0441\u0442\u0440\u0435\u043b\u043a\u043e\u0439 \u043d\u0430\u0437\u0430\u0434 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043f\u043e\u0438\u0441\u043a\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041e\u0431\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u043f\u043e\u0438\u0441\u043a\u0430 \u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u0439 \u0441\u0442\u0438\u043b\u044c:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u0432\u043e\u0434\u0438\u0442 \u0442\u0435\u043a\u0441\u0442, <code>onSearch<\/code> \u043e\u0431\u043d\u043e\u0432\u043b\u044f\u0435\u0442 \u0437\u0430\u043f\u0440\u043e\u0441 \u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041a\u043b\u0438\u043a \u043f\u043e \u0441\u0442\u0440\u0435\u043b\u043a\u0435 \u043d\u0430\u0437\u0430\u0434 \u0437\u0430\u0432\u0435\u0440\u0448\u0430\u0435\u0442 \u043f\u043e\u0438\u0441\u043a (<code>exitSearch()<\/code>).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0432\u0441\u0435 \u043f\u043e\u0434\u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0433\u043e\u0442\u043e\u0432\u044b, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u043c \u0438\u0445 \u0432 \u043d\u0430\u0448\u0435\u0439 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438.<\/p>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>Sidebar.tsx<\/code> \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>components<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">'use client'; import React, { useState, useEffect, RefObject } from 'react'; import clsx from 'clsx';  import Button from '.\/Button'; import ChatFolders from '.\/ChatFolders'; import { minWidth, defaultMaxWidth } from '@\/app\/a\/layout'; import useClickOutside from '@\/hooks\/useClickOutside';  enum SidebarView { \u00a0\u00a0Default, \u00a0\u00a0NewGroup, }  interface SidebarProps { \u00a0\u00a0width: number; \u00a0\u00a0setWidth: React.Dispatch&lt;React.SetStateAction&lt;number&gt;&gt;; }  export default function Sidebar({ width, setWidth }: SidebarProps) { \u00a0\u00a0const getMaxWidth = () =&gt; { \u00a0\u00a0\u00a0\u00a0const windowWidth = window.innerWidth; \u00a0\u00a0\u00a0\u00a0let newMaxWidth = defaultMaxWidth;  \u00a0\u00a0\u00a0\u00a0if (windowWidth &gt;= 1276) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newMaxWidth = Math.floor(windowWidth * 0.33); \u00a0\u00a0\u00a0\u00a0} else if (windowWidth &gt;= 926) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newMaxWidth = Math.floor(windowWidth * 0.4); \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0return newMaxWidth; \u00a0\u00a0};  \u00a0\u00a0const [maxWidth, setMaxWidth] = useState(getMaxWidth()); \u00a0\u00a0const [menuOpen, setMenuOpen] = useState(false); \u00a0\u00a0const [view, setView] = useState(SidebarView.Default);  \u00a0\u00a0const menuDomNode = useClickOutside(() =&gt; { \u00a0\u00a0\u00a0\u00a0setMenuOpen(false); \u00a0\u00a0}) as RefObject&lt;HTMLDivElement&gt;;  \u00a0\u00a0const toggleMenu = () =&gt; { \u00a0\u00a0\u00a0\u00a0setMenuOpen((prev) =&gt; !prev); \u00a0\u00a0};  \u00a0\u00a0const openNewGroupView = () =&gt; { \u00a0\u00a0\u00a0\u00a0setView(SidebarView.NewGroup); \u00a0\u00a0\u00a0\u00a0setMenuOpen(false); \u00a0\u00a0};  \u00a0\u00a0useEffect(() =&gt; { \u00a0\u00a0\u00a0\u00a0const calculateMaxWidth = () =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const newMaxWidth = getMaxWidth(); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setMaxWidth(newMaxWidth); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setWidth(width &gt;= newMaxWidth ? newMaxWidth : width); \u00a0\u00a0\u00a0\u00a0};  \u00a0\u00a0\u00a0\u00a0calculateMaxWidth();  \u00a0\u00a0\u00a0\u00a0window.addEventListener('resize', calculateMaxWidth);  \u00a0\u00a0\u00a0\u00a0return () =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0window.removeEventListener('resize', calculateMaxWidth); \u00a0\u00a0\u00a0\u00a0}; \u00a0\u00a0}, [setWidth, width]);  \u00a0\u00a0useEffect(() =&gt; { \u00a0\u00a0\u00a0\u00a0if (width) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0let newWidth = width; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (width &gt; maxWidth) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0newWidth = maxWidth; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setWidth(newWidth); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0localStorage.setItem('sidebarWidth', String(width)); \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0}, [width, maxWidth, setWidth]);  \u00a0\u00a0\/\/ \u041e\u0431\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u00a0\u00a0const handleResize = ( \u00a0\u00a0\u00a0\u00a0event: React.MouseEvent&lt;HTMLDivElement, MouseEvent&gt; \u00a0\u00a0) =&gt; { \u00a0\u00a0\u00a0\u00a0const startX = event.clientX; \u00a0\u00a0\u00a0\u00a0const startWidth = width;  \u00a0\u00a0\u00a0\u00a0const onMouseMove = (e: MouseEvent) =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const newWidth = Math.min( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Math.max(minWidth, startWidth + (e.clientX - startX)), \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0maxWidth \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setWidth(newWidth); \u00a0\u00a0\u00a0\u00a0};  \u00a0\u00a0\u00a0\u00a0const onMouseUp = () =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0window.removeEventListener('mousemove', onMouseMove); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0window.removeEventListener('mouseup', onMouseUp); \u00a0\u00a0\u00a0\u00a0};  \u00a0\u00a0\u00a0\u00a0window.addEventListener('mousemove', onMouseMove); \u00a0\u00a0\u00a0\u00a0window.addEventListener('mouseup', onMouseUp); \u00a0\u00a0};  \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"sidebar\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0style={{ width: ${width}px }} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"max-[600px]:!w-full max-[925px]:!w-[26.5rem] w-auto group bg-background h-full flex-shrink-0 relative\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onMouseLeave={() =&gt; setMenuOpen(false)} \u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\/* \u0412\u0438\u0434 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e *\/} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'contents', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0view === SidebarView.Default ? 'block' : 'hidden' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;ChatFolders \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\/* \u041a\u043d\u043e\u043f\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0447\u0430\u0442\u0430 *\/} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'absolute right-4 bottom-4 translate-y-20 transition-transform duration-[.25s] ease-[cubic-bezier(0.34,1.56,0.64,1)] group-hover:translate-y-0', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0menuOpen &amp;&amp; 'translate-y-0', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0view === SidebarView.NewGroup &amp;&amp; 'hidden' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0active \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0icon=\"new-chat-filled\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={toggleMenu} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx('sidebar-button', menuOpen ? 'active' : '')} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;i className=\"absolute icon icon-close\" \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{menuOpen &amp;&amp; ( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"fixed left-[-100vw] right-[-100vw] top-[-100vh] bottom-[-100vh] z-20\" \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0ref={menuDomNode} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'bg-background-compact-menu backdrop-blur-[10px] custom-scroll py-1 bottom-[calc(100%+0.5rem)] right-0 origin-bottom-right overflow-hiddden list-none absolute shadow-[0_.25rem_.5rem_.125rem_#72727240] rounded-xl min-w-[13.5rem] z-[21] overscroll-contain text-black transition-[opacity,_transform] duration-150 ease-[cubic-bezier(0.2,0.0.2,1)]', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0menuOpen \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0? 'block opacity-100 scale-100' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0: 'hidden opacity-0 scale-[.85]' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={openNewGroupView} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"text-sm my-[.125rem] mx-1 p-1 pe-3 rounded-md font-medium scale-100 transition-transform duration-150 ease-in-out bg-transparent flex items-center relative overflow-hidden leading-6 whitespace-nowrap text-black cursor-pointer\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;i \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"icon icon-group max-w-5 text-[1.25rem] me-5 ms-2 text-[#707579]\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0aria-hidden=\"true\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{'New Group'} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\/* \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 *\/} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"hidden lg:block absolute z-20 top-0 -right-1 h-full w-2 cursor-ew-resize\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onMouseDown={handleResize} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0); }<\/code><\/pre>\n<p>\u0412 \u043f\u0440\u0438\u0432\u0435\u0434\u0435\u043d\u043d\u043e\u043c \u0432\u044b\u0448\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0435:<\/p>\n<ul>\n<li>\n<p><strong>\u0423\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0448\u0438\u0440\u0438\u043d\u043e\u0439 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0428\u0438\u0440\u0438\u043d\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0440\u0430\u0441\u0441\u0447\u0438\u0442\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u043e\u043a\u043d\u0430 \u0438 \u043d\u0430\u0441\u0442\u0440\u0430\u0438\u0432\u0430\u0435\u0442\u0441\u044f \u0432 \u043e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u043d\u043e\u043c \u0434\u0438\u0430\u043f\u0430\u0437\u043e\u043d\u0435 (\u043e\u0442 <code>minWidth<\/code> \u0434\u043e <code>maxWidth<\/code>).<\/p>\n<\/li>\n<li>\n<p>\u0428\u0438\u0440\u0438\u043d\u0430 \u0441\u043e\u0445\u0440\u0430\u043d\u044f\u0435\u0442\u0441\u044f \u0432 localStorage \u0434\u043b\u044f \u0441\u043e\u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u043c\u0435\u0436\u0434\u0443 \u0441\u0435\u0430\u043d\u0441\u0430\u043c\u0438.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p><code>cursor-ew-resize<\/code> \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c \u0434\u043b\u044f \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f \u0440\u0430\u0437\u043c\u0435\u0440\u0430.<\/p>\n<\/li>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>handleResize<\/code> \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0440\u0443\u0435\u0442, \u0447\u0442\u043e \u0448\u0438\u0440\u0438\u043d\u0430 \u043e\u0441\u0442\u0430\u0435\u0442\u0441\u044f \u0432 \u0434\u043e\u043f\u0443\u0441\u0442\u0438\u043c\u044b\u0445 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u0445 \u043f\u0440\u0438 \u043f\u0435\u0440\u0435\u0442\u0430\u0441\u043a\u0438\u0432\u0430\u043d\u0438\u0438.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041e\u0442\u043e\u0431\u0440\u0430\u0436\u0435\u043d\u0438\u0435 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0411\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c \u0438\u043c\u0435\u0435\u0442 \u0434\u0432\u0430 \u0440\u0435\u0436\u0438\u043c\u0430:<\/p>\n<ol>\n<li>\n<p>\u0412\u0438\u0434 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e \u2013 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u0447\u0430\u0442\u043e\u0432 (ChatFolders).<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u043e\u0441\u043c\u043e\u0442\u0440 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b \u2013 \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f, \u043a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043a\u043d\u043e\u043f\u043a\u0443 &#171;<strong>New Group<\/strong>&#171;.<\/p>\n<\/li>\n<\/ol>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u0435\u0440\u0435\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435 \u043c\u0435\u043d\u044e \u0438 \u043a\u043b\u0438\u043a \u0432\u043d\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u0440\u0438 \u043d\u0430\u0436\u0430\u0442\u0438\u0438 \u043a\u043d\u043e\u043f\u043a\u0438 &#171;<strong>New Chat<\/strong>&#187; \u043e\u0442\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f \u043f\u043b\u0430\u0432\u0430\u044e\u0449\u0435\u0435 \u043c\u0435\u043d\u044e.<\/p>\n<\/li>\n<li>\n<p>\u0415\u0441\u043b\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043a\u043b\u0438\u043a\u0430\u0435\u0442 \u0437\u0430 \u043f\u0440\u0435\u0434\u0435\u043b\u0430\u043c\u0438 \u043c\u0435\u043d\u044e, \u043e\u043d\u043e \u0430\u0432\u0442\u043e\u043c\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438 \u0437\u0430\u043a\u0440\u044b\u0432\u0430\u0435\u0442\u0441\u044f (<code>useClickOutside()<\/code>).<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0441\u0442\u0438\u043b\u0435\u0439 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438<\/h3>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043e\u0444\u043e\u0440\u043c\u0438\u043c \u043d\u0430\u0448\u0443 \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c, \u0447\u0442\u043e\u0431\u044b \u043e\u043d\u0430 \u0445\u043e\u0440\u043e\u0448\u043e \u0441\u043e\u0447\u0435\u0442\u0430\u043b\u0430\u0441\u044c \u0441 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u043e\u043c \u0447\u0430\u0442\u0430.<\/p>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>globals.scss<\/code> \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>app<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 CSS-\u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">... #sidebar .str-chat.messaging.light.str-chat__channel-list.str-chat__channel-list-react { \u00a0\u00a0background: none; \u00a0\u00a0border: none; \u00a0\u00a0box-shadow: none; }  #sidebar  .str-chat.messaging.light.str-chat__channel-list.str-chat__channel-list-react&gt;div { \u00a0\u00a0padding: 0; }  #sidebar  .str-chat__channel-search { \u00a0\u00a0position: absolute; \u00a0\u00a0width: 100%; \u00a0\u00a0top: 0; \u00a0\u00a0left: 0; }  #sidebar .str-chat__channel-list-react .str-chat__channel-list-messenger-react { \u00a0\u00a0margin-top: 56px; }  #sidebar .str-chat__channel-search-result-list.inline { \u00a0\u00a0padding: 0.5rem; }  #sidebar .str-chat__channel-search-result { \u00a0\u00a0border-radius: 0.75rem; } ...<\/code><\/pre>\n<h3>\u0414\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0432 \u043c\u0430\u043a\u0435\u0442<\/h3>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c \u0432 \u043c\u0430\u043a\u0435\u0442 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<p>\u041e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>\/a\/layout.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">... import Sidebar from '@\/components\/Sidebar'; ...  export default function Layout({ children }: LayoutProps) { \u00a0\u00a0... \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;Chat client={chatClient!}&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;StreamVideo client={videoClient!}&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex h-full w-full\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Sidebar width={sidebarWidth} setWidth={setSidebarWidth} \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/StreamVideo&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/Chat&gt; \u00a0\u00a0); }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0438\u043c\u043f\u043e\u0440\u0442\u0438\u0440\u0443\u0435\u043c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>Sidebar<\/code>, \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u043c \u0435\u0433\u043e \u0432 \u043c\u0430\u043a\u0435\u0442 \u0438 \u0438 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u043c \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u044f \u0434\u043b\u044f \u0435\u0433\u043e \u043f\u0440\u043e\u043f\u043e\u0432 <code>width<\/code> \u0438 <code>setWidth<\/code>, \u0447\u0442\u043e\u0431\u044b \u043c\u043e\u0436\u043d\u043e \u0431\u044b\u043b\u043e \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0438\u0437\u043c\u0435\u043d\u044f\u0442\u044c \u0440\u0430\u0437\u043c\u0435\u0440.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8e3\/867\/881\/8e3867881bc8354419dd13aadbbc10da.gif\" width=\"1100\" height=\"658\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8e3\/867\/881\/8e3867881bc8354419dd13aadbbc10da.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/8e3\/867\/881\/8e3867881bc8354419dd13aadbbc10da.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u0433\u043e \u0447\u0430\u0442\u0430 \u043d\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438<\/h2>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c, \u043a\u043e\u0433\u0434\u0430 \u0443 \u043d\u0430\u0441 \u0435\u0441\u0442\u044c \u0431\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c, \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0441\u0442\u0430\u043d\u0435\u0442 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u044f \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u044b\u0445 \u0447\u0430\u0442\u043e\u0432. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043d\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u0438\u0435, \u043a\u043e\u0442\u043e\u0440\u043e\u0435 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c:<\/p>\n<ul>\n<li>\n<p>\u0414\u0430\u0432\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u043e\u043c\u0443 \u0447\u0430\u0442\u0443<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0431\u0438\u0440\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0432 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0447\u0430\u0442\u0430 \u0441 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u043c\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438<\/p>\n<\/li>\n<\/ul>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>components<\/code> \u043d\u043e\u0432\u044b\u0439 \u0444\u0430\u0439\u043b \u043f\u043e\u0434 \u0438\u043c\u0435\u043d\u0435\u043c <code>NewGroupView.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0442\u0443\u0434\u0430 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">import { ChangeEvent, useEffect, useMemo, useRef, useState } from 'react'; import { DefaultStreamChatGenerics, useChatContext } from 'stream-chat-react'; import { UserResponse } from 'stream-chat';  import Avatar from '.\/Avatar'; import Button from '.\/Button'; import RippleButton from '.\/RippleButton'; import Spinner from '.\/Spinner'; import { customAlphabet } from 'nanoid'; import { getLastSeen } from '..\/lib\/utils'; import clsx from 'clsx';  interface NewGroupViewProps { \u00a0\u00a0goBack: () =&gt; void; }  const NewGroupView = ({ goBack }: NewGroupViewProps) =&gt; { \u00a0\u00a0const { client } = useChatContext();  \u00a0\u00a0const [creatingGroup, setCreatingGroup] = useState(false); \u00a0\u00a0const [query, setQuery] = useState(''); \u00a0\u00a0const [groupName, setGroupName] = useState(''); \u00a0\u00a0const [users, setUsers] = useState&lt;UserResponse&lt;DefaultStreamChatGenerics&gt;[]&gt;( \u00a0\u00a0\u00a0\u00a0[] \u00a0\u00a0); \u00a0\u00a0const [originalUsers, setOriginalUsers] = useState&lt; \u00a0\u00a0\u00a0\u00a0UserResponse&lt;DefaultStreamChatGenerics&gt;[] \u00a0\u00a0&gt;([]); \u00a0\u00a0const [selectedUsers, setSelectedUsers] = useState&lt;string[]&gt;([]);  \u00a0\u00a0const debounceTimeout = useRef&lt;NodeJS.Timeout | null&gt;(null); \u00a0\u00a0const cancelled = useRef(false);  \u00a0\u00a0useEffect(() =&gt; { \u00a0\u00a0\u00a0\u00a0const getAllUsers = async () =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const userId = client.userID; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const { users } = await client.queryUsers( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ @ts-expect-error - id \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ id: { $ne: userId } }, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ id: 1, name: 1 }, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ limit: 20 } \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setUsers(users); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setOriginalUsers(users); \u00a0\u00a0\u00a0\u00a0}; \u00a0\u00a0\u00a0\u00a0getAllUsers(); \u00a0\u00a0\u00a0\u00a0\/\/ eslint-disable-next-line react-hooks\/exhaustive-deps \u00a0\u00a0}, []);  \u00a0\u00a0const handleUserSearch = async (e: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; { \u00a0\u00a0\u00a0\u00a0const query = e.target.value.trim(); \u00a0\u00a0\u00a0\u00a0setQuery(query); \u00a0\u00a0\u00a0\u00a0if (!query) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (debounceTimeout.current) clearTimeout(debounceTimeout.current); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0cancelled.current = true; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setUsers(originalUsers); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0cancelled.current = false;  \u00a0\u00a0\u00a0\u00a0if (debounceTimeout.current) clearTimeout(debounceTimeout.current); \u00a0\u00a0\u00a0\u00a0debounceTimeout.current = setTimeout(async () =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (cancelled.current) return;  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0try { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const userId = client.userID; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const { users } = await client.queryUsers( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$or: [ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ id: { $autocomplete: query } }, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ name: { $autocomplete: query } }, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0], \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/\/ @ts-expect-error - id \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id: { $ne: userId }, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ id: 1, name: 1 }, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{ limit: 5 } \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0);  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (!cancelled.current) setUsers(users); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} catch (error) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.error('Error fetching users:', error); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0}, 200); \u00a0\u00a0};  \u00a0\u00a0const leave = () =&gt; { \u00a0\u00a0\u00a0\u00a0setCreatingGroup(false); \u00a0\u00a0\u00a0\u00a0setGroupName(''); \u00a0\u00a0\u00a0\u00a0setQuery(''); \u00a0\u00a0\u00a0\u00a0setSelectedUsers([]); \u00a0\u00a0\u00a0\u00a0goBack(); \u00a0\u00a0};  \u00a0\u00a0const createNewGroup = async () =&gt; { \u00a0\u00a0\u00a0\u00a0if (!groupName) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0alert('Please enter a group name.'); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return; \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0if (selectedUsers.length &lt; 2) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0alert('Please select at least two users.'); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return; \u00a0\u00a0\u00a0\u00a0}  \u00a0\u00a0\u00a0\u00a0setCreatingGroup(true);  \u00a0\u00a0\u00a0\u00a0try { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ1234567890'; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const nanoid = customAlphabet(alphabet, 7); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0const group = client.channel('messaging', nanoid(7), { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: groupName, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0members: [...selectedUsers, client.userID!], \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0});  \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0await group.create(); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0leave(); \u00a0\u00a0\u00a0\u00a0} catch (error) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0console.error(error); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0alert('Error creating group'); \u00a0\u00a0\u00a0\u00a0} finally { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0setCreatingGroup(false); \u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0};  \u00a0\u00a0const onSelectUser = (e: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; { \u00a0\u00a0\u00a0\u00a0const userId = e.target.id; \u00a0\u00a0\u00a0\u00a0setSelectedUsers((prevSelectedUsers) =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (prevSelectedUsers.includes(userId)) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return prevSelectedUsers.filter((id) =&gt; id !== userId); \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return [...prevSelectedUsers, userId]; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0}); \u00a0\u00a0};  \u00a0\u00a0const sortedUsers = useMemo( \u00a0\u00a0\u00a0\u00a0() =&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0users.sort((a, b) =&gt; { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0if (selectedUsers.includes(a.id)) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return -1; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else if (selectedUsers.includes(b.id)) { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 1; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} else { \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0return 0; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}), \u00a0\u00a0\u00a0\u00a0[users, selectedUsers] \u00a0\u00a0);  \u00a0\u00a0return (  \u00a0\u00a0\u00a0\u00a0&lt;&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex items-center bg-background px-[.8125rem] pt-1.5 pb-2 gap-[1.375rem] h-[56px]\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;RippleButton onClick={leave} icon=\"arrow-left\" \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h3 className=\"text-[1.25rem] font-medium mr-auto select-none truncate\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0New Group \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/h3&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex flex-col px-5 h-[calc(100%-3.5rem)] overflow-hidden\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0htmlFor=\"groupName\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"relative block mt-5 py-[11px] px-[18px] rounded-xl border border-color-borders-input shadow-sm focus-within:border-primary focus-within:ring-1 focus-within:ring-primary\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"text\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"groupName\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={groupName} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={(e) =&gt; setGroupName(e.target.value)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"peer caret-primary border-none bg-transparent placeholder-transparent placeholder:text-base focus:border-transparent focus:outline-none focus:ring-0\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0placeholder=\"Group name\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;span className=\"pointer-events-none absolute start-[18px] top-0 -translate-y-1\/2 bg-white p-0.5 text-sm text-[#a2acb4] transition-all peer-placeholder-shown:top-1\/2 peer-placeholder-shown:text-base peer-focus:top-0 peer-focus:text-xs peer-focus:text-primary\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Group name \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/span&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;h3 className=\"my-4 mx-1 font-medium text-[1rem] text-color-text-secondary\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0Add members \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/h3&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;label \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0htmlFor=\"user\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"relative caret-primary block overflow-hidden border-b border-color-borders-input bg-transparent py-3 px-5 focus-within:border-primary\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"text\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"users\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0placeholder=\"Who would you like to add?\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0value={query} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={(e) =&gt; handleUserSearch(e)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"text-base h-8 w-full border-none bg-transparent p-0 placeholder:text-base focus:border-transparent focus:outline-none focus:ring-0\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/label&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;fieldset className=\"flex flex-col gap-2 mt-2 custom-scroll\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{sortedUsers.map((user) =&gt; ( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;UserCheckbox \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0key={user.id} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0user={user} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0checked={selectedUsers.includes(user.id)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={onSelectUser} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0))} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/fieldset&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"absolute right-4 bottom-4 transition-transform duration-[.25s] ease-[cubic-bezier(0.34,1.56,0.64,1)] translate-y-0\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Button \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0active \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0icon=\"arrow-right\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onClick={createNewGroup} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0disabled={creatingGroup} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx('sidebar-button', creatingGroup ? 'active' : '')} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"icon-loading absolute\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative w-6 h-6 before:relative before:content-none before:block before:pt-full\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Spinner \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/Button&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/&gt; \u00a0\u00a0); };  interface UserCheckboxProps { \u00a0\u00a0user: UserResponse&lt;DefaultStreamChatGenerics&gt;; \u00a0\u00a0checked: boolean; \u00a0\u00a0onChange: (e: ChangeEvent&lt;HTMLInputElement&gt;) =&gt; void; }  const UserCheckbox = ({ user, checked, onChange }: UserCheckboxProps) =&gt; {  \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;label \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0htmlFor={user.id} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"flex items-center gap-2 p-2 h-[3.5rem] rounded-xl hover:bg-chat-hover bg-background-compact-menu cursor-pointer\" \u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"relative h-10 w-10\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;Avatar \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0data={{ \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0name: user.name || ${user.first_name} ${user.last_name}, \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0image: user.image || '', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0width={40} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p className=\"text-base leading-5\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{user.name || ${user.first_name} ${user.last_name}} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/p&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;p className=\"text-sm text-color-text-meta\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{getLastSeen(user.last_active!)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/p&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"flex items-center ml-auto\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&amp;#8203; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;input \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id={user.id} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0type=\"checkbox\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0checked={checked} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0onChange={onChange} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className=\"size-4 rounded border-2 border-color-borders-input\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0&lt;\/label&gt; \u00a0\u00a0); };  export default NewGroupView;<\/code><\/pre>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u044d\u0442\u043e\u0433\u043e \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u0430:<\/p>\n<ul>\n<li>\n<p><strong>\u0418\u0437\u0432\u043b\u0435\u0447\u0435\u043d\u0438\u0435 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u0438\u0437\u0432\u043b\u0435\u043a\u0430\u0435\u0442 \u0441\u043f\u0438\u0441\u043e\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 (\u0438\u0441\u043a\u043b\u044e\u0447\u0430\u044f \u0442\u0435\u043a\u0443\u0449\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f) \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>client.queryUsers()<\/code>.<\/p>\n<\/li>\n<li>\n<p>\u0421\u043f\u0438\u0441\u043e\u043a \u0445\u0440\u0430\u043d\u0438\u0442\u0441\u044f \u0432 <code>users<\/code> \u0438 <code>originalUsers<\/code>, \u0447\u0442\u043e\u0431\u044b \u043e\u0431\u0435\u0441\u043f\u0435\u0447\u0438\u0442\u044c \u0444\u0438\u043b\u044c\u0442\u0440\u0430\u0446\u0438\u044e \u043f\u0440\u0438 \u043f\u043e\u0438\u0441\u043a\u0435.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u0438\u0441\u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439:<\/strong><\/p>\n<ul>\n<li>\n<p>\u0424\u0443\u043d\u043a\u0446\u0438\u044f <code>handleUserSearch<\/code> \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438 \u0444\u0438\u043b\u044c\u0442\u0440\u0443\u0435\u0442 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u043d\u0430 \u043e\u0441\u043d\u043e\u0432\u0435 \u0432\u0445\u043e\u0434\u043d\u044b\u0445 \u0434\u0430\u043d\u043d\u044b\u0445.<\/p>\n<\/li>\n<li>\n<p>Debounce-\u043c\u0435\u0445\u0430\u043d\u0438\u0437\u043c \u043f\u0440\u0435\u0434\u043e\u0442\u0432\u0440\u0430\u0449\u0430\u0435\u0442 \u0438\u0437\u0431\u044b\u0442\u043e\u0447\u043d\u044b\u0435 \u0432\u044b\u0437\u043e\u0432\u044b API.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432\u044b\u0431\u0438\u0440\u0430\u0435\u0442 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u0447\u0435\u043a\u0431\u043e\u043a\u0441\u043e\u0432.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c, \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0443\u043a\u0430\u0437\u0430\u0442\u044c \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435 \u0433\u0440\u0443\u043f\u043f\u044b.<\/p>\n<\/li>\n<li>\n<p>\u041f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u044b \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <code>nanoid()<\/code> \u0433\u0435\u043d\u0435\u0440\u0438\u0440\u0443\u0435\u0442\u0441\u044f \u0441\u043b\u0443\u0447\u0430\u0439\u043d\u044b\u0439 ID \u0438 \u0441\u043e\u0437\u0434\u0430\u0435\u0442\u0441\u044f \u043d\u043e\u0432\u044b\u0439 \u043a\u0430\u043d\u0430\u043b \u0447\u0430\u0442\u0430.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0439 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441 \u0438 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0435:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>\u041f\u043e\u043b\u044f \u0432\u0432\u043e\u0434\u0430:<\/strong> \u0412\u0432\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u043f\u043e\u0438\u0441\u043a\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u0434\u0438\u043d\u0430\u043c\u0438\u0447\u0435\u0441\u043a\u0438\u043c\u0438 \u043c\u0435\u0442\u043a\u0430\u043c\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0412\u044b\u0431\u043e\u0440 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u043e\u0432:<\/strong> \u041f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0441\u043e\u0440\u0442\u0438\u0440\u0443\u044e\u0442\u0441\u044f \u0432 \u0441\u043e\u043e\u0442\u0432\u0435\u0442\u0441\u0442\u0432\u0438\u0438 \u0441 \u0438\u0445 \u043f\u0440\u0438\u043e\u0440\u0438\u0442\u0435\u0442\u043e\u043c, \u043f\u0440\u0438 \u044d\u0442\u043e\u043c \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0435 \u0443\u0447\u0430\u0441\u0442\u043d\u0438\u043a\u0438 \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u044e\u0442\u0441\u044f \u0432\u0432\u0435\u0440\u0445\u0443 \u0441\u043f\u0438\u0441\u043a\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u0421\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f \u043a\u043d\u043e\u043f\u043a\u0438:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041a\u043d\u043e\u043f\u043a\u0430 &#171;<strong>Create<\/strong>&#187; \u043e\u0442\u043a\u043b\u044e\u0447\u0430\u0435\u0442\u0441\u044f \u043f\u0440\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0433\u0440\u0443\u043f\u043f\u044b.<\/p>\n<\/li>\n<li>\n<p>\u0412\u043e \u0432\u0440\u0435\u043c\u044f \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438 \u043f\u043e\u044f\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u0438\u043d\u0434\u0438\u043a\u0430\u0442\u043e\u0440 \u0437\u0430\u0433\u0440\u0443\u0437\u043a\u0438.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u0412\u043e\u0437\u0432\u0440\u0430\u0442 \u0438 \u0441\u0431\u0440\u043e\u0441 \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u044f:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041d\u0430\u0436\u0430\u0442\u0438\u0435 \u043a\u043d\u043e\u043f\u043a\u0438 \u043e\u0442\u043c\u0435\u043d\u044b \u0441\u0431\u0440\u0430\u0441\u044b\u0432\u0430\u0435\u0442 \u0444\u043e\u0440\u043c\u0443 \u0438 \u0443\u0434\u0430\u043b\u044f\u0435\u0442 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u044b\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<p>\u0414\u0430\u043b\u0435\u0435, \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u043d\u0430 \u0431\u043e\u043a\u043e\u0432\u0443\u044e \u043f\u0430\u043d\u0435\u043b\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>NewGroupView<\/code>, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u043c\u043e\u0433\u043b\u0438 \u043b\u0435\u0433\u043a\u043e \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f.<\/p>\n<p>\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u0444\u0430\u0439\u043b<code> \/components\/Sidebar.tsx<\/code> \u0438 \u0432\u043d\u0435\u0441\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f, \u0434\u043e\u0431\u0430\u0432\u0438\u0432 \u0432 \u043d\u0435\u0433\u043e <code>NewGroupView<\/code>:<\/p>\n<pre><code class=\"javascript\">... import NewGroupView from '.\/NewGroupView'; ...  export default function Sidebar({ width, setWidth }: SidebarProps) { \u00a0\u00a0...  \u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0id=\"sidebar\" \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... \u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\/* \u0412\u0438\u0434 \u043f\u043e \u0443\u043c\u043e\u043b\u0447\u0430\u043d\u0438\u044e *\/} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\/* \u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0439 \u0433\u0440\u0443\u043f\u043f\u044b *\/} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;div \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0className={clsx( \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'contents', \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0view === SidebarView.NewGroup ? 'block' : 'hidden' \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0)} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;NewGroupView goBack={() =&gt; setView(SidebarView.Default)} \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\/* \u041a\u043d\u043e\u043f\u043a\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043d\u043e\u0432\u043e\u0433\u043e \u0447\u0430\u0442\u0430 *\/} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{\/* \u0418\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u0435 \u0440\u0430\u0437\u043c\u0435\u0440\u0430 *\/} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0... \u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0); }<\/code><\/pre>\n<p>\u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u043d\u043e\u0432\u044b\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 \u043f\u043e\u0434 \u043d\u0430\u0437\u0432\u0430\u043d\u0438\u0435\u043c <code>NewGroupView<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0442\u0435\u043f\u0435\u0440\u044c \u043e\u0442\u043e\u0431\u0440\u0430\u0436\u0430\u0435\u0442\u0441\u044f \u0432 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0432 \u0437\u0430\u0432\u0438\u0441\u0438\u043c\u043e\u0441\u0442\u0438 \u043e\u0442 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f. \u041a\u043e\u0433\u0434\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u043d\u0430\u0436\u0438\u043c\u0430\u0435\u0442 \u043d\u0430 \u043a\u043d\u043e\u043f\u043a\u0443 \u201c<strong>New Group<\/strong>\u201d, \u0431\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c \u043c\u0435\u043d\u044f\u0435\u0442 \u0441\u0432\u043e\u0439 \u0432\u0438\u0434 \u043d\u0430 <code>NewGroupView<\/code>. \u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0433\u0440\u0443\u043f\u043f\u044b \u0438\u043b\u0438 \u043e\u0442\u043c\u0435\u043d\u044b \u043e\u043f\u0435\u0440\u0430\u0446\u0438\u0438 \u0431\u043e\u043a\u043e\u0432\u0430\u044f \u043f\u0430\u043d\u0435\u043b\u044c \u0432\u043e\u0437\u0432\u0440\u0430\u0449\u0430\u0435\u0442\u0441\u044f \u043a \u0441\u0432\u043e\u0435\u043c\u0443 \u043f\u0435\u0440\u0432\u043e\u043d\u0430\u0447\u0430\u043b\u044c\u043d\u043e\u043c\u0443 \u0432\u0438\u0434\u0443.<\/p>\n<figure class=\"full-width\"><img decoding=\"async\" src=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/329\/5ed\/7a8\/3295ed7a8ce927678a16dd870596bc89.gif\" width=\"780\" height=\"469\" sizes=\"auto, (max-width: 780px) 100vw, 50vw\" srcset=\"https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/329\/5ed\/7a8\/3295ed7a8ce927678a16dd870596bc89.gif 780w,&#10;       https:\/\/habrastorage.org\/getpro\/habr\/upload_files\/329\/5ed\/7a8\/3295ed7a8ce927678a16dd870596bc89.gif 781w\" loading=\"lazy\" decode=\"async\"\/><\/figure>\n<p>\u0412\u043e\u0442 \u0438 \u0432\u0441\u0435! \u0421 \u044d\u0442\u0438\u043c \u043e\u0431\u043d\u043e\u0432\u043b\u0435\u043d\u0438\u0435\u043c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0442\u0435\u043f\u0435\u0440\u044c \u043c\u043e\u0433\u0443\u0442 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043d\u043e\u0432\u044b\u0435 \u0433\u0440\u0443\u043f\u043f\u044b \u043f\u0440\u044f\u043c\u043e \u043d\u0430 \u0431\u043e\u043a\u043e\u0432\u043e\u0439 \u043f\u0430\u043d\u0435\u043b\u0438.<\/p>\n<h2>\u0417\u0430\u043a\u043b\u044e\u0447\u0435\u043d\u0438\u0435<\/h2>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u0441\u0435\u0440\u0438\u0438 \u043c\u044b \u0437\u0430\u043b\u043e\u0436\u0438\u043b\u0438 \u0444\u0443\u043d\u0434\u0430\u043c\u0435\u043d\u0442 \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043a\u043b\u043e\u043d\u0430 \u0432\u0435\u0431-\u0432\u0435\u0440\u0441\u0438\u0438 Telegram, \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0432 \u043f\u0440\u043e\u0435\u043a\u0442 Next.js, \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0432 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e Clerk \u0438 \u0441\u043e\u0437\u0434\u0430\u0432 \u0431\u0430\u0437\u043e\u0432\u044b\u0439 \u043c\u0430\u043a\u0435\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e TailwindCSS. \u041c\u044b \u0442\u0430\u043a\u0436\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043b\u0438 Stream SDK \u0438 \u0434\u043e\u0431\u0430\u0432\u0438\u043b\u0438 \u0432\u043e\u0437\u043c\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0433\u0440\u0443\u043f\u043f\u043e\u0432\u044b\u0435 \u0447\u0430\u0442\u044b.<\/p>\n<p>\u0412 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0438 \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0447\u0430\u0442\u0430 \u0438 \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/getstream.io\/chat\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">Stream React Chat SDK<\/a>.<\/p>\n<p>\u041f\u0440\u043e\u0434\u043e\u043b\u0436\u0435\u043d\u0438\u0435 \u0441\u043b\u0435\u0434\u0443\u0435\u0442\u2026<\/p>\n<hr\/>\n<p><strong>\u0425\u043e\u0442\u0438\u0442\u0435 \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u0442\u0430\u043a\u0438\u0435 \u0436\u0435 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0432\u0435\u0431-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u043a\u0430\u043a Telegram-\u043a\u043b\u043e\u043d \u043d\u0430 Next.js \u0438 TailwindCSS?  <\/strong><\/p>\n<p>\u0422\u043e\u0433\u0434\u0430 \u0432\u0430\u043c \u0442\u043e\u0447\u043d\u043e \u0441\u0442\u043e\u0438\u0442 \u043e\u0431\u0440\u0430\u0442\u0438\u0442\u044c \u0432\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u043d\u0430 <a href=\"https:\/\/otus.pw\/Ji8b\/\" rel=\"noopener noreferrer nofollow\">\u043a\u0443\u0440\u0441 <strong>JavaScript Developer. Basic<\/strong><\/a>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0441\u0442\u0430\u0440\u0442\u0443\u0435\u0442 <em>26 \u0438\u044e\u043d\u044f<\/em>. <\/p>\n<p>\u0410\u00a0\u0447\u0442\u043e\u0431\u044b \u0432\u044b \u0442\u043e\u0447\u043d\u043e \u043f\u043e\u043d\u044f\u043b\u0438, \u043a\u0430\u043a\u00a0\u0432\u0441\u0435 \u0443\u0441\u0442\u0440\u043e\u0435\u043d\u043e\u00a0\u2014 <strong>\u043c\u044b \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u0438\u043b\u0438 \u0434\u0432\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043e\u0442\u043a\u0440\u044b\u0442\u044b\u0445 \u0443\u0440\u043e\u043a\u0430<\/strong>, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043f\u0440\u044f\u043c\u0443\u044e \u0441\u0432\u044f\u0437\u0430\u043d\u044b \u0441\u00a0\u0442\u0435\u043c\u0430\u043c\u0438 \u044d\u0442\u043e\u0439 \u0441\u0442\u0430\u0442\u044c\u0438:<\/p>\n<ul>\n<li>\n<p> <a href=\"https:\/\/otus.pw\/n5FR\/\" rel=\"noopener noreferrer nofollow\">\u041c\u0430\u043d\u0438\u043f\u0443\u043b\u044f\u0446\u0438\u0438 \u0441\u00a0HTML \u0438 CSS \u0441\u00a0\u043f\u043e\u043c\u043e\u0449\u044c\u044e JavaScript<\/a>\u00a0\u2014 <em>10\u00a0\u0438\u044e\u043d\u044f, 18:00<\/em><\/p>\n<\/li>\n<li>\n<p> <a href=\"https:\/\/otus.pw\/yqTWl\/\" rel=\"noopener noreferrer nofollow\">\u0420\u0430\u0431\u043e\u0442\u0430 \u0441\u00a0\u043e\u0441\u043d\u043e\u0432\u043d\u044b\u043c\u0438 HTML\u2011\u0442\u0435\u0433\u0430\u043c\u0438 \u0438 \u0438\u0445 \u0430\u0442\u0440\u0438\u0431\u0443\u0442\u0430\u043c\u0438<\/a>\u00a0\u2014 <em>17\u00a0\u0438\u044e\u043d\u044f, 19:00<\/em> <\/p>\n<\/li>\n<\/ul>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/915946\/\"> https:\/\/habr.com\/ru\/articles\/915946\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<figure class=\"full-width\"><\/figure>\n<p>\u0420\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0430 \u0447\u0430\u0442-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043d\u0443\u043b\u044f \u043c\u043e\u0436\u0435\u0442 \u043f\u043e\u043a\u0430\u0437\u0430\u0442\u044c\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0441\u043b\u043e\u0436\u043d\u043e\u0439 \u0437\u0430\u0434\u0430\u0447\u0435\u0439. \u041d\u043e \u043f\u0440\u0438 \u043d\u0430\u043b\u0438\u0447\u0438\u0438 \u043f\u0440\u0430\u0432\u0438\u043b\u044c\u043d\u044b\u0445 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u0441\u0435 \u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u0441\u044f \u043d\u0430\u043c\u043d\u043e\u0433\u043e \u043f\u0440\u043e\u0449\u0435, \u0447\u0435\u043c \u0432\u044b \u0434\u0443\u043c\u0430\u0435\u0442\u0435.<\/p>\n<p>\u0412 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u0438\u0437 \u0442\u0440\u0435\u0445 \u0447\u0430\u0441\u0442\u0435\u0439 \u043c\u044b \u043f\u043e\u0434\u0440\u043e\u0431\u043d\u043e \u0440\u0430\u0441\u0441\u043c\u043e\u0442\u0440\u0438\u043c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f <a href=\"https:\/\/web.telegram.org\/\" rel=\"noopener noreferrer nofollow\">\u043a\u043b\u043e\u043d\u0430 \u0432\u0435\u0431-\u0432\u0435\u0440\u0441\u0438\u0438 Telegram<\/a> \u0441 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435\u043c Next.js, TailwindCSS \u0438 Stream SDK. \u0412 \u043f\u0435\u0440\u0432\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u043c \u0432\u0441\u0435 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b\u0435 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0438 \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u043c\u0430\u043a\u0435\u0442 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e TailwindCSS.<\/p>\n<p>\u0412\u043e \u0432\u0442\u043e\u0440\u043e\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0441\u043e\u0441\u0440\u0435\u0434\u043e\u0442\u043e\u0447\u0438\u043c\u0441\u044f \u043d\u0430 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u0434\u0438\u0430\u043b\u043e\u0433\u043e\u0432\u043e\u0439 \u0441\u0435\u043a\u0446\u0438\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0438 \u043e\u0431\u043c\u0435\u043d\u0430 \u0441\u043e\u043e\u0431\u0449\u0435\u043d\u0438\u044f\u043c\u0438 \u0432 \u0440\u0435\u0436\u0438\u043c\u0435 \u0440\u0435\u0430\u043b\u044c\u043d\u043e\u0433\u043e \u0432\u0440\u0435\u043c\u0435\u043d\u0438 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e <a href=\"https:\/\/getstream.io\/chat\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">Stream React Chat SDK<\/a>. \u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u0439 \u0447\u0430\u0441\u0442\u0438 \u043c\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0432\u0438\u0434\u0435\u043e- \u0438 \u0430\u0443\u0434\u0438\u043e\u0432\u044b\u0437\u043e\u0432\u044b \u0432 \u043d\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f <a href=\"https:\/\/getstream.io\/video\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">Stream React Video and Audio SDK<\/a>.<\/p>\n<p>\u041a \u043a\u043e\u043d\u0446\u0443 \u044d\u0442\u043e\u0439 \u0441\u0435\u0440\u0438\u0438 \u0443 \u0432\u0430\u0441 \u0431\u0443\u0434\u0435\u0442 \u043f\u043e\u043b\u043d\u043e\u0435 \u043f\u043e\u043d\u0438\u043c\u0430\u043d\u0438\u0435 \u0442\u043e\u0433\u043e, \u043a\u0430\u043a \u0440\u0430\u0431\u043e\u0442\u0430\u044e\u0442 \u0441\u043e\u0432\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0447\u0430\u0442-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f, \u0430 \u0442\u0430\u043a\u0436\u0435 \u043f\u043e\u043b\u043d\u043e\u0441\u0442\u044c\u044e \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u044c\u043d\u044b\u0439 \u043f\u0440\u043e\u0435\u043a\u0442, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u0432\u044b \u0441\u043c\u043e\u0436\u0435\u0442\u0435 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u0441\u0432\u043e\u0435\u0439 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u0439 \u0440\u0430\u0431\u043e\u0442\u0435.<\/p>\n<p>\u0412\u043e\u0442 \u043a\u0430\u043a \u0431\u0443\u0434\u0435\u0442 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u043a\u043e\u043d\u0435\u0447\u043d\u044b\u0439 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442:<\/p>\n<p><a href=\"https:\/\/youtu.be\/I6EnQlVdMpc\" rel=\"noopener noreferrer nofollow\">https:\/\/youtu.be\/I6EnQlVdMpc<\/a><\/p>\n<p>\u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u043f\u043e\u043f\u0440\u043e\u0431\u043e\u0432\u0430\u0442\u044c \u0432 \u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 <a href=\"https:\/\/telegram-clone-pink.vercel.app\/\" rel=\"noopener noreferrer nofollow\">\u0440\u0430\u0431\u043e\u0447\u0435\u0435 \u0434\u0435\u043c\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/a> \u0438 \u043d\u0430\u0439\u0442\u0438 \u0435\u0433\u043e \u043a\u043e\u0434 \u0432 \u044d\u0442\u043e\u043c <a href=\"https:\/\/github.com\/TropicolX\/telegram-clone\" rel=\"noopener noreferrer nofollow\">GitHub-\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<p>\u0427\u0442\u043e \u0436, \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u043f\u0440\u0438\u0441\u0442\u0443\u043f\u0438\u043c!<\/p>\n<h2>\u041f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u044b\u0435 \u0442\u0440\u0435\u0431\u043e\u0432\u0430\u043d\u0438\u044f<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0437\u0432\u043b\u0435\u0447\u044c \u043c\u0430\u043a\u0441\u0438\u043c\u0430\u043b\u044c\u043d\u0443\u044e \u043f\u043e\u043b\u044c\u0437\u0443 \u0438\u0437 \u044d\u0442\u043e\u0433\u043e \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0430, \u043f\u0440\u0435\u0436\u0434\u0435 \u0447\u0435\u043c \u043c\u044b \u043d\u0430\u0447\u043d\u0435\u043c, \u0443\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0432\u044b \u0437\u043d\u0430\u043a\u043e\u043c\u044b \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c\u0438 \u043a\u043e\u043d\u0446\u0435\u043f\u0446\u0438\u044f\u043c\u0438:<\/p>\n<ul>\n<li>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u044b React:<\/strong> \u0412\u044b \u0434\u043e\u043b\u0436\u043d\u044b \u0437\u043d\u0430\u0442\u044c, \u043a\u0430\u043a \u0441\u043e\u0437\u0434\u0430\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b, \u0443\u043f\u0440\u0430\u0432\u043b\u044f\u0442\u044c \u0441\u043e\u0441\u0442\u043e\u044f\u043d\u0438\u0435\u043c \u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0441 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u043d\u043e\u0439 \u0430\u0440\u0445\u0438\u0442\u0435\u043a\u0442\u0443\u0440\u043e\u0439 React.<\/p>\n<\/li>\n<li>\n<p><strong>Node.js &amp; npm:<\/strong> \u0423\u0431\u0435\u0434\u0438\u0442\u0435\u0441\u044c, \u0447\u0442\u043e \u0443 \u0432\u0430\u0441 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u043b\u0435\u043d\u044b Node.js \u0438 npm, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043e\u043d\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u044b \u0434\u043b\u044f \u0437\u0430\u043f\u0443\u0441\u043a\u0430 \u0438 \u0441\u0431\u043e\u0440\u043a\u0438 \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430.<\/p>\n<\/li>\n<li>\n<p><strong>\u041e\u0441\u043d\u043e\u0432\u044b TypeScript, Next.js \u0438 TailwindCSS:<\/strong> \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0430\u043a\u0442\u0438\u0432\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443, \u0438\u043c\u0435\u044f \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0437\u043d\u0430\u043d\u0438\u044f \u043e \u043d\u0438\u0445, \u0432\u0430\u043c \u0431\u0443\u0434\u0435\u0442 \u043b\u0435\u0433\u0447\u0435 \u0440\u0430\u0437\u043e\u0431\u0440\u0430\u0442\u044c\u0441\u044f \u0432 \u044d\u0442\u043e\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435.<\/p>\n<\/li>\n<\/ul>\n<h2>\u041f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0430 \u043f\u0440\u043e\u0435\u043a\u0442\u0430<\/h2>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u043f\u043e\u0434\u0433\u043e\u0442\u043e\u0432\u043a\u0438 \u043f\u0440\u043e\u0435\u043a\u0442\u0430. \u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0449\u0438\u0439 \u0432\u0435\u0441\u044c \u0448\u0430\u0431\u043b\u043e\u043d\u043d\u044b\u0439 \u043a\u043e\u0434, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043d\u0430\u043c \u043d\u0443\u0436\u0435\u043d \u0434\u043b\u044f \u043d\u0430\u0447\u0430\u043b\u0430 \u0440\u0430\u0431\u043e\u0442\u044b.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u043a\u043b\u043e\u043d\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u0448\u0430\u0431\u043b\u043e\u043d, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<pre><code class=\"javascript\">git clone https:\/\/github.com\/TropicolX\/telegram-clone.git cd telegram-clone git checkout starter npm install<\/code><\/pre>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u043a\u043e\u043c\u0430\u043d\u0434 \u0441\u0442\u0440\u0443\u043a\u0442\u0443\u0440\u0430 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0434\u043e\u043b\u0436\u043d\u0430 \u0432\u044b\u0433\u043b\u044f\u0434\u0435\u0442\u044c \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043e\u0431\u0440\u0430\u0437\u043e\u043c:<\/p>\n<figure class=\"\"><\/figure>\n<p>\u042d\u0442\u043e\u0442 \u0448\u0430\u0431\u043b\u043e\u043d \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u043d\u0430\u0448 Next.js \u0441\u0435\u0442\u0430\u043f \u0441 \u043f\u0440\u0435\u0434\u0432\u0430\u0440\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0435\u043d\u043d\u044b\u043c\u0438 TypeScript \u0438 TailwindCSS. \u041e\u043d \u0442\u0430\u043a\u0436\u0435 \u0432\u043a\u043b\u044e\u0447\u0430\u0435\u0442 \u0432 \u0441\u0435\u0431\u044f \u0434\u0440\u0443\u0433\u0438\u0435 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u043c\u043e\u0434\u0443\u043b\u0438 \u0438 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0432 \u044d\u0442\u043e\u043c \u0440\u0443\u043a\u043e\u0432\u043e\u0434\u0441\u0442\u0432\u0435, \u0432 \u0442\u043e\u043c \u0447\u0438\u0441\u043b\u0435:<\/p>\n<ul>\n<li>\n<p><code>components<\/code>: \u0417\u0434\u0435\u0441\u044c \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u043e\u0432\u0442\u043e\u0440\u043d\u043e \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c\u044b\u0435 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b.<\/p>\n<\/li>\n<li>\n<p><code>hooks<\/code>: \u0412 \u044d\u0442\u043e\u0439 \u043f\u0430\u043f\u043a\u0435 \u0431\u0443\u0434\u0443\u0442 \u0441\u043e\u0434\u0435\u0440\u0436\u0430\u0442\u044c\u0441\u044f \u0432\u0441\u0435 \u043d\u0430\u0448\u0438 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u0435 React-\u0445\u0443\u043a\u0438.<\/p>\n<\/li>\n<li>\n<p><code>lib<\/code>: \u042d\u0442\u0430 \u043f\u0430\u043f\u043a\u0430 \u0441\u043e\u0434\u0435\u0440\u0436\u0438\u0442 \u0444\u0430\u0439\u043b<code> utils.ts<\/code>, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043c\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u043c \u0434\u043b\u044f \u0445\u0440\u0430\u043d\u0435\u043d\u0438\u044f \u0441\u043b\u0443\u0436\u0435\u0431\u043d\u044b\u0445 \u0444\u0443\u043d\u043a\u0446\u0438\u0439.<\/p>\n<\/li>\n<\/ul>\n<h2>\u0410\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e Clerk<\/h2>\n<p>\u0427\u0442\u043e\u0431\u044b \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 Telegram Web, \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0438 \u0434\u043e\u043b\u0436\u043d\u044b \u0432\u043e\u0439\u0442\u0438 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443. \u041f\u043e\u044d\u0442\u043e\u043c\u0443 \u043c\u044b \u0442\u043e\u0436\u0435 \u0434\u043e\u0431\u0430\u0432\u0438\u043c \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u044e \u0432 \u043d\u0430\u0448 \u043a\u043b\u043e\u043d \u0438 \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u0434\u043b\u044f \u044d\u0442\u043e\u0433\u043e Clerk.<\/p>\n<h4>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Clerk?<\/h4>\n<p><a href=\"https:\/\/clerk.com\/\" rel=\"noopener noreferrer nofollow\">Clerk<\/a> \u2014 \u044d\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430 \u0434\u043b\u044f \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f\u043c\u0438. \u041e\u043d\u0430 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442 \u0448\u0438\u0440\u043e\u043a\u0438\u0439 \u043d\u0430\u0431\u043e\u0440 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u043e\u0432 \u0434\u043b\u044f \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0438 \u043f\u0440\u043e\u0444\u0438\u043b\u0435\u0439 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439, \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0449\u0438\u0439 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430, API \u0438 \u043f\u0430\u043d\u0435\u043b\u044c \u043c\u043e\u043d\u0438\u0442\u043e\u0440\u0438\u043d\u0433\u0430 \u0434\u043b\u044f \u0430\u0434\u043c\u0438\u043d\u0438\u0441\u0442\u0440\u0430\u0442\u043e\u0440\u043e\u0432.<\/p>\n<p>\u042d\u0442\u043e\u0442 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0441\u0442\u0438\u0442 \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u0438\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432 \u043d\u0430\u0448 Telegram-\u043a\u043b\u043e\u043d.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Clerk<\/h3>\n<figure class=\"full-width\">\n<div><figcaption>Clerk sign-up page<\/figcaption><\/div>\n<\/figure>\n<p>\u0427\u0442\u043e\u0431\u044b \u043d\u0430\u0447\u0430\u0442\u044c \u0440\u0430\u0431\u043e\u0442\u0443 \u0441 Clerk, \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c \u043d\u0430 \u0438\u0445 \u0432\u0435\u0431-\u0441\u0430\u0439\u0442\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 <a href=\"https:\/\/dashboard.clerk.com\/sign-up\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 Clerk<\/a> \u0438 \u0437\u0430\u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0438\u0440\u0443\u0439\u0442\u0435\u0441\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0438\u043b\u0438 \u043a\u0430\u043a\u043e\u0439-\u043d\u0438\u0431\u0443\u0434\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u0439 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u044b\u0439 \u0430\u043a\u043a\u0430\u0443\u043d\u0442.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Clerk<\/h3>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u0445\u043e\u0434\u0430 \u0432 \u0441\u0438\u0441\u0442\u0435\u043c\u0443 \u0432\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u0442\u044c \u043f\u0440\u043e\u0435\u043a\u0442 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ol>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f \u0438 \u043d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;<strong>Create application<\/strong>&#171;.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0437\u043e\u0432\u0438\u0442\u0435 \u0441\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u201c<strong>Telegram clone<\/strong>\u201d.<\/p>\n<\/li>\n<li>\n<p>\u0412 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 \u201c<strong>Sign in options<\/strong>\u201d \u0432\u044b\u0431\u0435\u0440\u0438\u0442\u0435 <strong>Email<\/strong>, <strong>Username<\/strong>, \u0438 <strong>Google<\/strong>.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;<strong>Create application<\/strong>&#171;, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043f\u0440\u043e\u0446\u0435\u0441\u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438.<\/p>\n<\/li>\n<\/ol>\n<figure class=\"full-width\">\n<div><figcaption>Clerk dashboard steps<\/figcaption><\/div>\n<\/figure>\n<p>\u041a\u0430\u043a \u0442\u043e\u043b\u044c\u043a\u043e \u043f\u0440\u043e\u0435\u043a\u0442 \u0431\u0443\u0434\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d, \u0432\u044b \u043f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0435 \u043e\u0431\u0437\u043e\u0440\u0430 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0417\u0434\u0435\u0441\u044c \u0432\u044b \u043d\u0430\u0439\u0434\u0435\u0442\u0435 \u0441\u0432\u043e\u0438 <strong>Publishable Key<\/strong> \u0438 <strong>Secret Key<\/strong> \u2014 \u043e\u0431\u044f\u0437\u0430\u0442\u0435\u043b\u044c\u043d\u043e \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u0435 \u0438\u0445, \u043e\u043d\u0438 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0432\u0430\u043c \u0432 \u0434\u0430\u043b\u044c\u043d\u0435\u0439\u0448\u0435\u043c.<\/p>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u043e \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c \u0432 \u043f\u0440\u043e\u0446\u0435\u0441\u0441\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u043c\u043e\u0433 \u0432\u0432\u0435\u0441\u0442\u0438 \u0441\u0432\u043e\u0438 \u0438\u043c\u044f \u0438 \u0444\u0430\u043c\u0438\u043b\u0438\u044e, \u043f\u043e\u0434\u043e\u0431\u043d\u043e \u0442\u043e\u043c\u0443, \u043a\u0430\u043a \u044d\u0442\u043e \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0432 Telegram. \u0412\u044b \u043c\u043e\u0436\u0435\u0442\u0435 \u0430\u043a\u0442\u0438\u0432\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u044d\u0442\u0443 \u0444\u0443\u043d\u043a\u0446\u0438\u044e, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0432 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ol>\n<li>\n<p>\u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 \u00a0\u0432\u043a\u043b\u0430\u0434\u043a\u0443 <strong>&#171;Configure<\/strong>&#187; \u043d\u0430 \u0441\u0432\u043e\u0435\u0439 \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0439\u0434\u0438\u0442\u0435 \u043e\u043f\u0446\u0438\u044e &#171;<strong>Name<\/strong>&#187; \u0432 \u0440\u0430\u0437\u0434\u0435\u043b\u0435 &#171;<strong>Personal Information<\/strong>&#187; \u0438 \u0432\u043a\u043b\u044e\u0447\u0438\u0442\u0435 \u0435\u0435.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043d\u0430 \u0437\u043d\u0430\u0447\u043e\u043a \u0448\u0435\u0441\u0442\u0435\u0440\u0435\u043d\u043a\u0438 \u0440\u044f\u0434\u043e\u043c \u0441 \u043f\u043e\u043b\u0435\u043c &#171;<strong>Name<\/strong>&#187; \u0438 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0435\u0433\u043e \u043f\u043e \u0441\u0432\u043e\u0435\u043c\u0443 \u0443\u0441\u043c\u043e\u0442\u0440\u0435\u043d\u0438\u044e.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u201c<strong>Continue<\/strong>\u201d, \u0447\u0442\u043e\u0431\u044b \u0441\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u0438\u0437\u043c\u0435\u043d\u0435\u043d\u0438\u044f.<\/p>\n<\/li>\n<\/ol>\n<h3>\u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 Clerk \u0432 \u0432\u0430\u0448\u0435\u043c \u043f\u0440\u043e\u0435\u043a\u0442\u0435<\/h3>\n<p>\u0414\u0430\u043b\u0435\u0435 \u0434\u0430\u0432\u0430\u0439\u0442\u0435 \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u043c Clerk \u0432 \u0432\u0430\u0448 <a href=\"http:\/\/next.js\" rel=\"noopener noreferrer nofollow\">Next.js<\/a> \u043f\u0440\u043e\u0435\u043a\u0442. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<ol>\n<li>\n<p>\u0427\u0442\u043e\u0431\u044b \u0443\u0441\u0442\u0430\u043d\u043e\u0432\u0438\u0442\u044c Next.js SDK Clerk, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0439\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0443\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u0443:<\/p>\n<p><code>npm install @clerk\/nextjs<\/code><\/p>\n<\/li>\n<li>\n<p>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 <code>.env.local<\/code>-\u0444\u0430\u0439\u043b \u0432 \u043a\u043e\u0440\u043d\u0435\u0432\u043e\u043c \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0435 \u0441\u0440\u0435\u0434\u044b:<\/p>\n<\/li>\n<\/ol>\n<p><code>NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=your_clerk_publishable_key<\/code><\/p>\n<p><code>\u00a0CLERK_SECRET_KEY=your_clerk_secret_key<\/code><\/p>\n<p>       \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u0435 <code>your_clerk_publishable_key<\/code> \u0438 <code>your_clerk_secret_key<\/code> \u043a\u043b\u044e\u0447\u0430\u043c\u0438 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u043e\u0431\u0437\u043e\u0440\u0430 \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Clerk.<\/p>\n<p>   3.\u0427\u0442\u043e\u0431\u044b \u0438\u043c\u0435\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f \u043a \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u0438\u043c \u0434\u0430\u043d\u043d\u044b\u043c \u0438 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438 \u0432\u043e \u0432\u0441\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438,                     \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043e\u0431\u0435\u0440\u043d\u0443\u0442\u044c \u043d\u0430\u0448 \u043e\u0441\u043d\u043e\u0432\u043d\u043e\u0439 \u043c\u0430\u043a\u0435\u0442 \u0432 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442 <code>&lt;ClerkProvider \/&gt;<\/code> Clerk.\u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043e\u0442\u043a\u0440\u043e\u0439\u0442\u0435 \u0444\u0430\u0439\u043b <code>app\/layout.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u0435:<\/p>\n<pre><code class=\"javascript\">import type { Metadata } from 'next'; \u00a0import { ClerkProvider } from '@clerk\/nextjs';  \u00a0...  \u00a0export default function RootLayout({ \u00a0\u00a0\u00a0children, \u00a0}: Readonly&lt;{ \u00a0\u00a0\u00a0children: React.ReactNode; \u00a0}&gt;) { \u00a0\u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0\u00a0&lt;ClerkProvider&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;html lang=\"en\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;body className=\"h-svh w-svw lg:h-screen lg:w-screen antialiased text-color-text select-none overflow-hidden\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0{children} \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/body&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/html&gt; \u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/ClerkProvider&gt; \u00a0\u00a0\u00a0); \u00a0}<\/code><\/pre>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043b\u043e\u0433\u0438\u043d\u0430<\/h3>\n<p>\u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u0432 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u043a\u0435 \u043d\u0430\u0448\u0435\u0433\u043e Telegram-\u043a\u043b\u043e\u043d\u0430 \u0441\u0442\u0430\u043d\u0435\u0442 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0438 \u043b\u043e\u0433\u0438\u043d\u0430. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u043c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Clerk <code>&lt;SignUp \/&gt;<\/code> \u0438 <code>&lt;SignIn \/&gt;<\/code>. \u042d\u0442\u0438 \u043a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b \u0432\u043a\u043b\u044e\u0447\u0430\u044e\u0442 \u0432 \u0441\u0435\u0431\u044f \u0432\u0441\u0435 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044c\u0441\u043a\u043e\u0433\u043e \u0438\u043d\u0442\u0435\u0440\u0444\u0435\u0439\u0441\u0430 \u0438 \u043b\u043e\u0433\u0438\u043a\u0443 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u043d\u0430\u043c \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f.<\/p>\n<p>\u0427\u0442\u043e\u0431\u044b \u0434\u043e\u0431\u0430\u0432\u0438\u0442\u044c \u044d\u0442\u0438 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u044b \u0432 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435, \u0432\u044b\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u0448\u0430\u0433\u0438:<\/p>\n<p><strong>       1.\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 URL-\u0430\u0434\u0440\u0435\u0441\u0430 \u0430\u0443\u0442\u0435\u043d\u0442\u0438\u0444\u0438\u043a\u0430\u0446\u0438\u0438:<\/strong> \u041a\u043e\u043c\u043f\u043e\u043d\u0435\u043d\u0442\u044b Clerk <code>&lt;SignUp \/&gt;<\/code> \u0438 <code>&lt;SignIn \/&gt;<\/code> \u0442\u0440\u0435\u0431\u0443\u044e\u0442, \u0447\u0442\u043e\u0431\u044b \u043c\u044b \u0443\u043a\u0430\u0437\u0430\u043b\u0438, \u0433\u0434\u0435 \u043e\u043d\u0438 \u0440\u0430\u0441\u043f\u043e\u043b\u043e\u0436\u0435\u043d\u044b \u0432 \u043d\u0430\u0448\u0435\u043c \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0438. \u041c\u044b \u043c\u043e\u0436\u0435\u043c \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u044d\u0442\u043e \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043f\u0435\u0440\u0435\u043c\u0435\u043d\u043d\u044b\u0445 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u044f. \u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0435 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0432 \u0432\u0430\u0448 <code>.env.local<\/code>-\u0444\u0430\u0439\u043b:<\/p>\n<pre><code class=\"javascript\">NEXT_PUBLIC_CLERK_SIGN_IN_URL=\/sign-in \u00a0NEXT_PUBLIC_CLERK_SIGN_UP_URL=\/sign-up<\/code><\/pre>\n<p><strong>       2.\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438:<\/strong> \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0444\u0430\u0439\u043b \u043f\u043e \u0430\u0434\u0440\u0435\u0441\u0443 <code>app\/sign-up\/[[...sign-up]]\/page.tsx<\/code> \u0438 \u0434\u043e\u0431\u0430\u0432\u044c\u0442\u0435 \u0432 \u043d\u0435\u0433\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u0439 \u043a\u043e\u0434:<\/p>\n<pre><code class=\"javascript\">import { SignUp } from '@clerk\/nextjs';  \u00a0export default function Page() { \u00a0\u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0\u00a0&lt;div className=\"sm:w-svw sm:h-svh py-4 bg-background w-full h-full flex items-center justify-center\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;SignUp \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0); \u00a0}<\/code><\/pre>\n<p><strong>       3.\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0432\u0445\u043e\u0434\u0430:<\/strong> \u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0430\u043d\u0430\u043b\u043e\u0433\u0438\u0447\u043d\u044b\u0439 \u0444\u0430\u0439\u043b <code>page.tsx<\/code> \u0432 \u043f\u0430\u043f\u043a\u0435 <code>app\/sign-in\/[[...sign-in]]<\/code> \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">import { SignIn } from '@clerk\/nextjs';  \u00a0export default function Page() { \u00a0\u00a0\u00a0return ( \u00a0\u00a0\u00a0\u00a0&lt;div className=\"w-svw h-svh bg-background flex items-center justify-center\"&gt; \u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0&lt;SignIn \/&gt; \u00a0\u00a0\u00a0\u00a0\u00a0&lt;\/div&gt; \u00a0\u00a0\u00a0); \u00a0}<\/code><\/pre>\n<p><strong>      4.\u0414\u043e\u0431\u0430\u0432\u044c\u0442\u0435 Clerk Middleware:<\/strong> \u0421\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u0448\u0430\u0433\u043e\u043c \u043c\u044b \u0441\u043e\u0437\u0434\u0430\u0434\u0438\u043c \u0432\u0441\u043f\u043e\u043c\u043e\u0433\u0430\u0442\u0435\u043b\u044c\u043d\u043e\u0435 middleware \u0434\u043b\u044f \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0438 \u043d\u0430\u0448\u0438\u0445 \u0437\u0430\u0449\u0438\u0449\u0435\u043d\u043d\u044b\u0445 \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432. \u041d\u0430\u0448\u0430 \u0446\u0435\u043b\u044c \u2014 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0434\u043e\u0441\u0442\u0443\u043f\u043d\u044b\u043c\u0438 \u0434\u043b\u044f \u0432\u0441\u0435\u0445 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u0435\u0439 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u044b \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438, \u0437\u0430\u043a\u0440\u044b\u0432 \u0432\u0441\u0435 \u043e\u0441\u0442\u0430\u043b\u044c\u043d\u044b\u0435. \u0414\u043b\u044f \u044d\u0442\u043e\u0433\u043e \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u0432 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0435 <code>src<\/code> \u0444\u0430\u0439\u043b<code> middleware.ts<\/code> \u0441\u043e \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0438\u043c \u043a\u043e\u0434\u043e\u043c:<\/p>\n<pre><code class=\"javascript\">import { clerkMiddleware, createRouteMatcher } from '@clerk\/nextjs\/server';  \u00a0const isPublicRoute = createRouteMatcher(['\/sign-in(.*)', '\/sign-up(.*)']);  \u00a0export default clerkMiddleware(async (auth, request) =&gt; { \u00a0\u00a0\u00a0if (!isPublicRoute(request)) { \u00a0\u00a0\u00a0\u00a0\u00a0await auth.protect(); \u00a0\u00a0\u00a0} \u00a0});  \u00a0export const config = { \u00a0\u00a0\u00a0matcher: [ \u00a0\u00a0\u00a0\u00a0\u00a0\/\/ \u041f\u0440\u043e\u043f\u0443\u0441\u043a\u0430\u0435\u043c \u0432\u043d\u0443\u0442\u0440\u0435\u043d\u043d\u0438\u0435 \u0444\u0430\u0439\u043b\u044b Next.js \u0438 \u0432\u0441\u0435 \u0441\u0442\u0430\u0442\u0438\u0447\u0435\u0441\u043a\u0438\u0435 \u0444\u0430\u0439\u043b\u044b, \u0435\u0441\u043b\u0438 \u043e\u043d\u0438 \u043d\u0435 \u043d\u0430\u0439\u0434\u0435\u043d\u044b \u0432 \u043f\u0430\u0440\u0430\u043c\u0435\u0442\u0440\u0430\u0445 \u043f\u043e\u0438\u0441\u043a\u0430  \u00a0\u00a0\u00a0\u00a0\u00a0'\/((?!_next|[^?]*\\\\.(?:html?|css|js(?!on)|jpe?g|webp|png|gif|svg|ttf|woff2?|ico|csv|docx?|xlsx?|zip|webmanifest)).*)', \u00a0\u00a0\u00a0\u00a0\u00a0\/\/ \u0412\u0441\u0435\u0433\u0434\u0430 \u0437\u0430\u043f\u0443\u0441\u043a\u0430\u0435\u0442\u0441\u044f \u0434\u043b\u044f \u043c\u0430\u0440\u0448\u0440\u0443\u0442\u043e\u0432 API \u00a0\u00a0\u00a0\u00a0\u00a0'\/(api|trpc)(.*)', \u00a0\u00a0\u00a0], \u00a0};<\/code><\/pre>\n<figure class=\"full-width\"><\/figure>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u044d\u0442\u0438\u0445 \u0448\u0430\u0433\u043e\u0432 Clerk \u0431\u0443\u0434\u0435\u0442 \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u043d \u0432 \u0432\u0430\u0448\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0432\u043c\u0435\u0441\u0442\u0435 \u0441\u043e \u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0430\u043c\u0438 \u0432\u0445\u043e\u0434\u0430 \u0438 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438.<\/p>\n<h2>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430 Stream<\/h2>\n<h4>What is Stream?<\/h4>\n<h4>\u0427\u0442\u043e \u0442\u0430\u043a\u043e\u0435 Stream?<\/h4>\n<p><a href=\"https:\/\/getstream.io\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">Stream<\/a> \u2014 \u044d\u0442\u043e \u043f\u043b\u0430\u0442\u0444\u043e\u0440\u043c\u0430, \u043a\u043e\u0442\u043e\u0440\u0430\u044f \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0447\u0438\u043a\u0430\u043c \u043b\u0435\u0433\u043a\u043e \u0438\u043d\u0442\u0435\u0433\u0440\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0440\u0430\u0441\u0448\u0438\u0440\u0435\u043d\u043d\u044b\u0435 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0447\u0430\u0442\u0430 \u0438 \u0432\u0438\u0434\u0435\u043e \u0432 \u0441\u0432\u043e\u0438 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f. \u0412\u043c\u0435\u0441\u0442\u043e \u0442\u043e\u0433\u043e \u0447\u0442\u043e\u0431\u044b \u0441\u0430\u043c\u043e\u0441\u0442\u043e\u044f\u0442\u0435\u043b\u044c\u043d\u043e \u0440\u0430\u0437\u0440\u0430\u0431\u0430\u0442\u044b\u0432\u0430\u0442\u044c \u044d\u0442\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0438 \u0441 \u043d\u0443\u043b\u044f, Stream \u043f\u0440\u0435\u0434\u043b\u0430\u0433\u0430\u0435\u0442 API \u0438 SDK, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0437\u043d\u0430\u0447\u0438\u0442\u0435\u043b\u044c\u043d\u043e \u0443\u043f\u0440\u043e\u0449\u0430\u044e\u0442 \u043f\u0440\u043e\u0446\u0435\u0441\u0441.<\/p>\n<p>\u041c\u044b \u0431\u0443\u0434\u0435\u043c \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u044c <a href=\"https:\/\/getstream.io\/video\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">React SDK for Video<\/a> \u0438 <a href=\"https:\/\/getstream.io\/chat\/sdk\/react\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">React Chat SDK<\/a> Stream \u0434\u043b\u044f \u0440\u0435\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438 \u0444\u0443\u043d\u043a\u0446\u0438\u0439 \u0447\u0430\u0442\u0430 \u0438 \u0432\u0438\u0434\u0435\u043e\u0437\u0432\u043e\u043d\u043a\u043e\u0432 \u0432 \u043d\u0430\u0448\u0435\u043c Telegram-\u043a\u043b\u043e\u043d\u0435.<\/p>\n<h3>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Stream<\/h3>\n<figure class=\"full-width\"><\/figure>\n<p>\u0414\u0430\u0432\u0430\u0439\u0442\u0435 \u043d\u0430\u0447\u043d\u0435\u043c \u0441 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u0443\u0447\u0435\u0442\u043d\u043e\u0439 \u0437\u0430\u043f\u0438\u0441\u0438 Stream:<\/p>\n<ol>\n<li>\n<p><strong>\u0420\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u044f:<\/strong> \u041f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u043d\u0430 <a href=\"https:\/\/getstream.io\/accounts\/signup\/?utm_source=externalwriter&amp;utm_medium=referral&amp;utm_content=&amp;utm_campaign=Oluwabusayo\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u0440\u0430\u043d\u0438\u0446\u0443 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 Stream<\/a> \u0438 \u0441\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u0443\u044e \u0443\u0447\u0435\u0442\u043d\u0443\u044e \u0437\u0430\u043f\u0438\u0441\u044c, \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u044f \u0441\u0432\u043e\u0439 \u0430\u0434\u0440\u0435\u0441 \u044d\u043b\u0435\u043a\u0442\u0440\u043e\u043d\u043d\u043e\u0439 \u043f\u043e\u0447\u0442\u044b \u0438\u043b\u0438 \u043b\u043e\u0433\u0438\u043d \u0432 \u0441\u043e\u0446\u0438\u0430\u043b\u044c\u043d\u043e\u0439 \u0441\u0435\u0442\u0438.<\/p>\n<\/li>\n<li>\n<p><strong>\u0417\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u0435 \u0441\u0432\u043e\u0439 \u043f\u0440\u043e\u0444\u0438\u043b\u044c:<\/strong><\/p>\n<ul>\n<li>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0440\u0435\u0433\u0438\u0441\u0442\u0440\u0430\u0446\u0438\u0438 \u0432\u0430\u0441 \u043f\u043e\u043f\u0440\u043e\u0441\u044f\u0442 \u043f\u0440\u0435\u0434\u043e\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0443\u044e \u0438\u043d\u0444\u043e\u0440\u043c\u0430\u0446\u0438\u044e, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043e \u0432\u0430\u0448\u0435\u043c \u0440\u043e\u0434\u0435 \u0434\u0435\u044f\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0438 \u043e\u0442\u0440\u0430\u0441\u043b\u0438.<\/p>\n<\/li>\n<li>\n<p>\u0412\u044b\u0431\u0435\u0440\u0438\u0442\u0435 \u00a0\u043e\u043f\u0446\u0438\u0438 &#171;<strong>Chat Messaging<\/strong>&#187; \u0438 &#171;<strong>Video and Audio<\/strong>&#171;, \u043f\u043e\u0441\u043a\u043e\u043b\u044c\u043a\u0443 \u043d\u0430\u043c \u043d\u0443\u0436\u043d\u044b \u044d\u0442\u0438 \u0438\u043d\u0441\u0442\u0440\u0443\u043c\u0435\u043d\u0442\u044b \u0434\u043b\u044f \u043d\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f.<\/p>\n<figure class=\"full-width\">\n<div><figcaption>Strem sign up options<\/figcaption><\/div>\n<\/figure>\n<\/li>\n<li>\n<p>\u041d\u0430\u043a\u043e\u043d\u0435\u0446, \u043d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;<strong>Complete Signup<\/strong>&#171;, \u0447\u0442\u043e\u0431\u044b \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0438\u0442\u044c.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<\/ol>\n<p>\u041f\u043e\u0441\u043b\u0435 \u0432\u044b\u043f\u043e\u043b\u043d\u0435\u043d\u0438\u044f \u043e\u043f\u0438\u0441\u0430\u043d\u043d\u044b\u0445 \u0432\u044b\u0448\u0435 \u0448\u0430\u0433\u043e\u0432 \u0432\u044b \u0431\u0443\u0434\u0435\u0442\u0435 \u043f\u0435\u0440\u0435\u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u043f\u0430\u043d\u0435\u043b\u044c \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f Stream.<\/p>\n<h2>\u0421\u043e\u0437\u0434\u0430\u043d\u0438\u0435 \u043d\u043e\u0432\u043e\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430 Stream<\/h2>\n<figure class=\"full-width\"><\/figure>\n<p>\u0422\u0435\u043f\u0435\u0440\u044c \u0432\u0430\u043c \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e \u043d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c Stream-\u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435 \u0434\u043b\u044f \u0432\u0430\u0448\u0435\u0433\u043e \u043f\u0440\u043e\u0435\u043a\u0442\u0430:<\/p>\n<ol>\n<li>\n<p><strong>\u0421\u043e\u0437\u0434\u0430\u0439\u0442\u0435 \u043d\u043e\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/strong> \u0412 \u043f\u0440\u0430\u0432\u043e\u043c \u0432\u0435\u0440\u0445\u043d\u0435\u043c \u0443\u0433\u043b\u0443 \u043f\u0430\u043d\u0435\u043b\u0438 \u0443\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u044f Stream \u043d\u0430\u0436\u043c\u0438\u0442\u0435 &#171;Create App&#187;.<\/p>\n<\/li>\n<li>\n<p><strong>\u041d\u0430\u0441\u0442\u0440\u043e\u0439\u0442\u0435 \u0441\u0432\u043e\u0435 \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u0435:<\/strong><\/p>\n<ul>\n<li>\n<p><strong>App Name:<\/strong> \u0412\u0432\u0435\u0434\u0438\u0442\u0435 \u043f\u043e\u0434\u0445\u043e\u0434\u044f\u0449\u0435\u0435 \u0438\u043c\u044f, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440 &#171;<strong>the-telegram-clone<\/strong>&#171;, \u0438\u043b\u0438 \u043b\u044e\u0431\u043e\u0435 \u0434\u0440\u0443\u0433\u043e\u0435 \u0438\u043c\u044f \u043f\u043e \u0432\u0430\u0448\u0435\u043c\u0443 \u0432\u044b\u0431\u043e\u0440\u0443.<\/p>\n<\/li>\n<li>\n<p><strong>Region:<\/strong> \u0414\u043b\u044f \u043e\u043f\u0442\u0438\u043c\u0430\u043b\u044c\u043d\u043e\u0439 \u043f\u0440\u043e\u0438\u0437\u0432\u043e\u0434\u0438\u0442\u0435\u043b\u044c\u043d\u043e\u0441\u0442\u0438 \u0440\u0435\u043a\u043e\u043c\u0435\u043d\u0434\u0443\u0435\u0442\u0441\u044f \u0432\u044b\u0431\u0440\u0430\u0442\u044c \u0431\u043b\u0438\u0436\u0430\u0439\u0448\u0438\u0439 \u043a \u0432\u0430\u043c \u0440\u0435\u0433\u0438\u043e\u043d.<\/p>\n<\/li>\n<li>\n<p><strong>Environment:<\/strong> \u041e\u0441\u0442\u0430\u0432\u044c\u0442\u0435 \u0432 \u044d\u0442\u043e\u0439 \u043e\u043f\u0446\u0438\u0438 \u0437\u043d\u0430\u0447\u0435\u043d\u0438\u0435 &#171;<strong>Development<\/strong>&#171;.<\/p>\n<\/li>\n<li>\n<p>\u041d\u0430\u0436\u043c\u0438\u0442\u0435 \u043a\u043d\u043e\u043f\u043a\u0443 &#171;<strong>Create App<\/strong>&#171;, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u0432\u0435\u0440\u0448\u0438\u0442\u044c \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0443.<\/p>\n<\/li>\n<\/ul>\n<\/li>\n<li>\n<p><strong>\u041f\u043e\u043b\u0443\u0447\u0438\u0442\u0435 \u043a\u043b\u044e\u0447\u0438 API<\/strong>: \u041f\u043e\u0441\u043b\u0435 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043f\u0440\u0438\u043b\u043e\u0436\u0435\u043d\u0438\u044f \u043f\u0435\u0440\u0435\u0439\u0434\u0438\u0442\u0435 \u0432 \u0440\u0430\u0437\u0434\u0435\u043b &#171;<strong>App Access Keys<\/strong>&#171;. \u042d\u0442\u0438 \u043a\u043b\u044e\u0447\u0438 \u043f\u043e\u043d\u0430\u0434\u043e\u0431\u044f\u0442\u0441\u044f \u0432\u0430\u043c \u0434\u043b\u044f<\/p>\n<\/li>\n<\/ol>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-462446","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/462446","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=462446"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/462446\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=462446"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=462446"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=462446"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}