{"_id":"@baranov-guru/react-telegram-widgets","_rev":"3-b6aa351cb3e7c9bba2e180ef0741bf78","name":"@baranov-guru/react-telegram-widgets","dist-tags":{"latest":"1.1.0"},"versions":{"1.0.0":{"name":"@baranov-guru/react-telegram-widgets","version":"1.0.0","keywords":["react","telegram","widget","post","comments","discussion","embed"],"author":{"url":"Nejivoi","name":"Alexey Baranov","email":"https://github.com/Nejivoi"},"license":"MIT","_id":"@baranov-guru/react-telegram-widgets@1.0.0","maintainers":[{"name":"nejivoi","email":"mail4ba@gmail.com"}],"homepage":"https://github.com/baranov-guru/react-telegram-widgets#readme","bugs":{"url":"https://github.com/baranov-guru/react-telegram-widgets/issues"},"dist":{"shasum":"1137de595d60e63673697c7bc55b7d9304b3e6c2","tarball":"https://registry.npmjs.org/@baranov-guru/react-telegram-widgets/-/react-telegram-widgets-1.0.0.tgz","fileCount":13,"integrity":"sha512-yXUwdG687k4xLdORQQJ84AvcsQrB1JkDBxXo7LZneyhidSwfYzL0v4tW7AcHh7xAdlVI0Zdh2USyB+NGdIAIng==","signatures":[{"sig":"MEUCIHF5QyGJxmqQ5yoG2vkn4WmGFthfUQ58O1MdEeqAjk49AiEAm9uaGs6kyOrFLvOkL+Tn/KwcKyiNPpvyo1tOiy4g/NY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@baranov-guru%2freact-telegram-widgets@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":46525},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.esm.js","engines":{"node":">=18.0.0"},"gitHead":"5a89ca9fb61d46f0268d7fb4b0ad3f4fdc23eec4","scripts":{"dev":"rollup -c -w","lint":"eslint src --ext .ts,.tsx","test":"jest","build":"rollup -c","check":"npm run lint && npm run format:check && npm run test","clean":"rimraf dist","format":"prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:watch":"jest --watch","format:check":"prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\"","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"nejivoi","email":"mail4ba@gmail.com"},"repository":{"url":"git+https://github.com/baranov-guru/react-telegram-widgets.git","type":"git"},"_npmVersion":"10.8.2","description":"React components for embedding Telegram posts and comments widgets","directories":{},"_nodeVersion":"18.20.8","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","tslib":"^2.8.1","eslint":"^9.31.0","rimraf":"^5.0.0","rollup":"^3.0.0","ts-jest":"^29.0.0","prettier":"^3.0.0","@eslint/js":"^9.31.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0","rollup-plugin-dts":"^5.0.0","eslint-plugin-react":"^7.33.0","eslint-plugin-import":"^2.29.0","@testing-library/react":"^14.0.0","eslint-config-prettier":"^10.1.5","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-prettier":"^5.0.0","jest-environment-jsdom":"^29.0.0","@rollup/plugin-commonjs":"^25.0.0","@rollup/plugin-typescript":"^11.0.0","@testing-library/jest-dom":"^6.0.0","@typescript-eslint/parser":"^8.36.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^15.0.0","@typescript-eslint/eslint-plugin":"^8.36.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-dom":">=16.8.0"},"_npmOperationalInternal":{"tmp":"tmp/react-telegram-widgets_1.0.0_1752412407013_0.7888786582999625","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@baranov-guru/react-telegram-widgets","version":"1.0.1","keywords":["react","telegram","widget","post","comments","discussion","embed"],"author":{"url":"Nejivoi","name":"Alexey Baranov","email":"https://github.com/Nejivoi"},"license":"MIT","_id":"@baranov-guru/react-telegram-widgets@1.0.1","maintainers":[{"name":"nejivoi","email":"mail4ba@gmail.com"}],"homepage":"https://github.com/baranov-guru/react-telegram-widgets#readme","bugs":{"url":"https://github.com/baranov-guru/react-telegram-widgets/issues"},"dist":{"shasum":"dbc2062520072614dc924d6b1eac235dda409fb4","tarball":"https://registry.npmjs.org/@baranov-guru/react-telegram-widgets/-/react-telegram-widgets-1.0.1.tgz","fileCount":13,"integrity":"sha512-9OFCqmBkLKQ2LzzMinnINIT+iym4Y4rBzH9URKkv/sFoe2WBLmJwK65ivHlcG05I2Xze/99/FjFx5IujRK926A==","signatures":[{"sig":"MEYCIQCHdRUOD26r4i/LFoNdR46FJ22hBd2gC2jXkQGPwKLILAIhANwnpMGEnCs1GxOVgQc097fFUsRyjxbubDNXrjgzr42S","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@baranov-guru%2freact-telegram-widgets@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":47105},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.esm.js","engines":{"node":">=18.0.0"},"gitHead":"b1b73d5a5603f73aa532b7aeb47918bb060daa29","scripts":{"dev":"rollup -c -w","lint":"eslint src --ext .ts,.tsx","test":"jest","build":"rollup -c","check":"npm run lint && npm run format:check && npm run test","clean":"rimraf dist","format":"prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:watch":"jest --watch","format:check":"prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\"","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build"},"_npmUser":{"name":"nejivoi","email":"mail4ba@gmail.com"},"repository":{"url":"git+https://github.com/baranov-guru/react-telegram-widgets.git","type":"git"},"_npmVersion":"10.8.2","description":"React components for embedding Telegram posts and comments widgets","directories":{},"_nodeVersion":"18.20.8","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","tslib":"^2.8.1","eslint":"^9.31.0","rimraf":"^5.0.0","rollup":"^3.0.0","ts-jest":"^29.0.0","prettier":"^3.0.0","@eslint/js":"^9.31.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0","rollup-plugin-dts":"^5.0.0","eslint-plugin-react":"^7.33.0","eslint-plugin-import":"^2.29.0","@testing-library/react":"^14.0.0","eslint-config-prettier":"^10.1.5","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-prettier":"^5.0.0","jest-environment-jsdom":"^29.0.0","@rollup/plugin-commonjs":"^25.0.0","@rollup/plugin-typescript":"^11.0.0","@testing-library/jest-dom":"^6.0.0","@typescript-eslint/parser":"^8.36.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^15.0.0","@typescript-eslint/eslint-plugin":"^8.36.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-dom":">=16.8.0"},"_npmOperationalInternal":{"tmp":"tmp/react-telegram-widgets_1.0.1_1752571563043_0.8834377724729381","host":"s3://npm-registry-packages-npm-production"}},"1.1.0":{"_id":"@baranov-guru/react-telegram-widgets@1.1.0","bugs":{"url":"https://github.com/baranov-guru/react-telegram-widgets/issues"},"dist":{"shasum":"34a18d512df443e8e59b49a4b7c2c4daae2fae9a","tarball":"https://registry.npmjs.org/@baranov-guru/react-telegram-widgets/-/react-telegram-widgets-1.1.0.tgz","fileCount":20,"integrity":"sha512-3lDQigBLYfadh5pb0n9tbVB3aI8F0YNhMgF6uPcB5pOYLX+W/OuLvtxh3UEIq5OtbZo1YewnyH3vOLBpDT6sww==","signatures":[{"sig":"MEYCIQCHuw66TWHQYGz6FCGczM5RsHfDsRKxqRGEB6WpQegA5wIhAOlfOs4WfLxfWlchZB+Z+2WN1f5aBNlH4w5yKutK2CD8","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"},{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCICxRouIKpI/HSv/gH/QHO/RlrxSrthz+yGmY6BIdAXOnAiEA7t3mKPGc5rCfVOpYkN1RIX4tyofRympjgc6GCUCbFuE="}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@baranov-guru%2freact-telegram-widgets@1.1.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":153803},"main":"dist/index.js","name":"@baranov-guru/react-telegram-widgets","types":"dist/index.d.ts","author":{"url":"Nejivoi","name":"Alexey Baranov","email":"https://github.com/Nejivoi"},"module":"dist/index.esm.js","engines":{"node":">=18.0.0"},"gitHead":"8ea5d1a43831888e4fae7839f859217b490aa958","license":"MIT","scripts":{"dev":"rollup -c -w","lint":"eslint src --ext .ts,.tsx","test":"jest","build":"rollup -c","check":"npm run lint && npm run format:check && npm run test","clean":"rimraf dist","format":"prettier --write \"src/**/*.{ts,tsx,js,jsx,json,md}\"","lint:fix":"eslint src --ext .ts,.tsx --fix","test:watch":"jest --watch","format:check":"prettier --check \"src/**/*.{ts,tsx,js,jsx,json,md}\"","test:coverage":"jest --coverage","prepublishOnly":"npm run clean && npm run build"},"version":"1.1.0","_npmUser":{"name":"GitHub Actions","email":"npm-oidc-no-reply@github.com","trustedPublisher":{"id":"github","oidcConfigId":"oidc:fddea584-c672-47fa-b9c5-b8e6855a13fc"}},"homepage":"https://github.com/baranov-guru/react-telegram-widgets#readme","keywords":["react","telegram","widget","post","comments","discussion","login","share","auth","oidc","embed"],"repository":{"url":"git+https://github.com/baranov-guru/react-telegram-widgets.git","type":"git"},"_npmVersion":"11.19.0","description":"React components for embedding Telegram posts, comments, login, and share widgets","directories":{},"maintainers":[{"name":"nejivoi","email":"mail4ba@gmail.com"}],"_nodeVersion":"24.20.0","_hasShrinkwrap":false,"devDependencies":{"jest":"^29.0.0","tslib":"^2.8.1","eslint":"^9.31.0","rimraf":"^5.0.0","rollup":"^3.0.0","ts-jest":"^29.0.0","prettier":"^3.0.0","@eslint/js":"^9.31.0","typescript":"^5.0.0","@types/jest":"^29.0.0","@types/react":"^18.0.0","@types/react-dom":"^18.0.0","rollup-plugin-dts":"^5.0.0","eslint-plugin-react":"^7.33.0","eslint-plugin-import":"^2.29.0","@testing-library/react":"^14.0.0","eslint-config-prettier":"^10.1.5","eslint-plugin-jsx-a11y":"^6.8.0","eslint-plugin-prettier":"^5.0.0","jest-environment-jsdom":"^29.0.0","@rollup/plugin-commonjs":"^25.0.0","@rollup/plugin-typescript":"^11.0.0","@testing-library/jest-dom":"^6.0.0","@typescript-eslint/parser":"^8.36.0","eslint-plugin-react-hooks":"^5.2.0","@rollup/plugin-node-resolve":"^15.0.0","@typescript-eslint/eslint-plugin":"^8.36.0","rollup-plugin-peer-deps-external":"^2.2.4"},"peerDependencies":{"react":">=16.8.0","react-dom":">=16.8.0"},"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/react-telegram-widgets_1.1.0_1790157211066_0.8823078986485644"}}},"time":{"created":"2025-07-13T13:13:26.930Z","modified":"2026-09-23T09:53:31.524Z","1.0.0":"2025-07-13T13:13:27.179Z","1.0.1":"2025-07-15T09:26:03.206Z","1.1.0":"2026-09-23T09:53:31.150Z"},"bugs":{"url":"https://github.com/baranov-guru/react-telegram-widgets/issues"},"author":{"url":"Nejivoi","name":"Alexey Baranov","email":"https://github.com/Nejivoi"},"license":"MIT","homepage":"https://github.com/baranov-guru/react-telegram-widgets#readme","keywords":["react","telegram","widget","post","comments","discussion","login","share","auth","oidc","embed"],"repository":{"url":"git+https://github.com/baranov-guru/react-telegram-widgets.git","type":"git"},"description":"React components for embedding Telegram posts, comments, login, and share widgets","maintainers":[{"name":"nejivoi","email":"mail4ba@gmail.com"}],"readme":"# @baranov-guru/react-telegram-widgets\n\n[![npm version](https://img.shields.io/npm/v/@baranov-guru/react-telegram-widgets.svg)](https://www.npmjs.com/package/@baranov-guru/react-telegram-widgets)\n[![npm downloads](https://img.shields.io/npm/dm/@baranov-guru/react-telegram-widgets.svg)](https://www.npmjs.com/package/@baranov-guru/react-telegram-widgets)\n[![npm license](https://img.shields.io/npm/l/@baranov-guru/react-telegram-widgets.svg)](https://github.com/baranov-guru/react-telegram-widgets/blob/main/LICENSE)\n[![GitHub Actions](https://img.shields.io/github/actions/workflow/status/baranov-guru/react-telegram-widgets/ci.yml?branch=main)](https://github.com/baranov-guru/react-telegram-widgets/actions)\n[![Codecov](https://img.shields.io/codecov/c/github/baranov-guru/react-telegram-widgets)](https://codecov.io/gh/baranov-guru/react-telegram-widgets)\n[![GitHub issues](https://img.shields.io/github/issues/baranov-guru/react-telegram-widgets.svg)](https://github.com/baranov-guru/react-telegram-widgets/issues)\n[![GitHub pull requests](https://img.shields.io/github/issues-pr/baranov-guru/react-telegram-widgets.svg)](https://github.com/baranov-guru/react-telegram-widgets/pulls)\n[![TypeScript](https://img.shields.io/badge/TypeScript-007ACC?logo=typescript&logoColor=white)](https://www.typescriptlang.org/)\n[![React](https://img.shields.io/badge/React-20232A?logo=react&logoColor=61DAFB)](https://reactjs.org/)\n\nReact components for embedding Telegram posts, comments, login, and share widgets in your web applications.\n\n> 📖 **Official Documentation**: This package is based on the [Telegram Widget API](https://core.telegram.org/widgets). For detailed information about widget configuration and options, please refer to the official documentation.\n\n## Installation\n\n```bash\nnpm install @baranov-guru/react-telegram-widgets\n```\n\nor\n\n```bash\nyarn add @baranov-guru/react-telegram-widgets\n```\n\n## Usage\n\n### TelegramPostWidget\n\nEmbed a Telegram post in your React application:\n\n```tsx\nimport { TelegramPostWidget } from '@baranov-guru/react-telegram-widgets';\n\nfunction App() {\n  return (\n    <div>\n      <h1>My Blog Post</h1>\n      <p>Check out this Telegram post:</p>\n      <TelegramPostWidget\n        post='baranov_guru/61'\n        width='100%'\n        dark={true}\n        onLoad={() => console.log('Post loaded successfully!')}\n        onError={error => console.error('Failed to load post:', error)}\n      />\n    </div>\n  );\n}\n```\n\n### TelegramDiscussionWidget\n\nEmbed Telegram comments for a discussion:\n\n```tsx\nimport { TelegramDiscussionWidget } from '@baranov-guru/react-telegram-widgets';\n\nfunction App() {\n  return (\n    <div>\n      <h1>Discussion</h1>\n      <TelegramDiscussionWidget\n        discussion='baranov_guru/61'\n        commentsLimit={10}\n        height={400}\n        color='#ff0000'\n        colorful={true}\n        dark={true}\n        onLoad={() => console.log('Comments loaded!')}\n        onError={error => console.error('Failed to load comments:', error)}\n      />\n    </div>\n  );\n}\n```\n\n### TelegramLoginWidget\n\nLog in with Telegram using the current [OpenID Connect login library](https://core.telegram.org/widgets/login).\n\nRegister your site origin in @BotFather (Login Widget → Allowed URLs) and use the numeric **Client ID**.\n\n> Important: `telegram-login.js` uses a popup. If your site sends `Cross-Origin-Opener-Policy: same-origin`, login will fail. Use `same-origin-allow-popups` (or remove the header).\n\n```tsx\nimport {\n  TelegramLoginWidget,\n  TelegramLoginSuccess,\n} from '@baranov-guru/react-telegram-widgets';\n\nfunction LoginPage() {\n  const handleAuth = async (result: TelegramLoginSuccess) => {\n    // Send id_token to your backend and verify it there (see Server-side verification).\n    await fetch('/api/auth/telegram', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify({ id_token: result.id_token }),\n    });\n  };\n\n  return (\n    <TelegramLoginWidget\n      clientId={123456789}\n      scope={['profile', 'write']}\n      onAuth={handleAuth}\n      onError={error => console.error('Login failed:', error)}\n    />\n  );\n}\n```\n\nHeadless usage with the hook:\n\n```tsx\nimport { useTelegramLogin } from '@baranov-guru/react-telegram-widgets';\n\nfunction CustomLoginButton() {\n  const { login, isReady, isLoading, error } = useTelegramLogin({\n    clientId: 123456789,\n    scope: ['profile'],\n    onAuth: result => console.log(result.id_token, result.user),\n  });\n\n  return (\n    <button type='button' disabled={!isReady || isLoading} onClick={() => login()}>\n      Continue with Telegram\n    </button>\n  );\n}\n```\n\n### TelegramLegacyLoginWidget\n\nEmbed the [legacy iframe Login Widget](https://core.telegram.org/widgets/login-legacy) (payload with `hash`). Prefer `TelegramLoginWidget` for new integrations.\n\n```tsx\nimport {\n  TelegramLegacyLoginWidget,\n  TelegramLegacyLoginData,\n} from '@baranov-guru/react-telegram-widgets';\n\nfunction LegacyLoginPage() {\n  const handleAuth = async (user: TelegramLegacyLoginData) => {\n    await fetch('/api/auth/telegram-legacy', {\n      method: 'POST',\n      headers: { 'Content-Type': 'application/json' },\n      body: JSON.stringify(user),\n    });\n  };\n\n  return (\n    <TelegramLegacyLoginWidget\n      botName='SampleBot'\n      size='large'\n      radius={8}\n      requestAccess={true}\n      onAuth={handleAuth}\n      onError={error => console.error('Login widget error:', error)}\n    />\n  );\n}\n```\n\nYou can also redirect after legacy login with `authUrl` instead of (or in addition to) `onAuth`.\n\n### TelegramShareWidget\n\nEmbed a [Telegram Sharing Button](https://core.telegram.org/widgets/share):\n\n```tsx\nimport { TelegramShareWidget } from '@baranov-guru/react-telegram-widgets';\n\nfunction ShareSection() {\n  return (\n    <TelegramShareWidget\n      url='https://example.com/article'\n      comment='Check out this article!'\n      size='large'\n    />\n  );\n}\n```\n\n## API Reference\n\n### TelegramPostWidget Props\n\n| Prop        | Type                               | Default      | Description                                                                    |\n| ----------- | ---------------------------------- | ------------ | ------------------------------------------------------------------------------ |\n| `post`      | `string`                           | **required** | The post identifier in format \"channel/post_id\" (e.g., \"baranov_guru/1\") |\n| `userpic`   | `boolean \\| \"auto\"`                | `\"auto\"`     | Whether to show user pictures. \"auto\" shows them only if post contains them    |\n| `width`     | `CSSProperties[\"width\"] \\| \"100%\"` | `\"100%\"`     | The width of the widget                                                        |\n| `dark`      | `boolean`                          | `false`      | Enable dark theme                                                              |\n| `className` | `string`                           | -            | Optional CSS class for the container                                           |\n| `onError`   | `(e: unknown) => void`             | -            | Callback when an error occurs                                                  |\n| `onLoad`    | `() => void`                       | -            | Callback when the widget loads successfully                                    |\n\n### TelegramDiscussionWidget Props\n\n| Prop            | Type                   | Default      | Description                                                                                                                    |\n| --------------- | ---------------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------ |\n| `discussion`    | `string`               | **required** | The discussion identifier in format \"channel/post_id\" or just \"channel\" (e.g., \"baranov_guru/1\" or \"baranov_guru\") |\n| `commentsLimit` | `number`               | `5`          | Maximum number of comments to display                                                                                          |\n| `height`        | `number`               | -            | Height of the widget in pixels                                                                                                 |\n| `color`         | `string`               | -            | Color of widget elements (hex format, e.g., \"#cbcbcb\")                                                                         |\n| `colorful`      | `boolean`              | `false`      | Enable colorful usernames                                                                                                      |\n| `dark`          | `boolean`              | `false`      | Enable dark theme                                                                                                              |\n| `className`     | `string`               | -            | Optional CSS class for the container                                                                                           |\n| `onError`       | `(e: unknown) => void` | -            | Callback when an error occurs                                                                                                  |\n| `onLoad`        | `() => void`           | -            | Callback when the widget loads successfully                                                                                    |\n\n### TelegramLoginWidget Props\n\n| Prop        | Type                                                         | Default  | Description                                                                 |\n| ----------- | ------------------------------------------------------------ | -------- | --------------------------------------------------------------------------- |\n| `clientId`  | `number`                                                     | **required** | Bot Client ID from @BotFather                                           |\n| `scope`     | `Array<\"profile\" \\| \"phone\" \\| \"write\">`                     | -        | Optional scopes (`write` ≈ bot messaging permission in the JS API)          |\n| `lang`      | `string`                                                     | -        | Optional UI language code                                                   |\n| `nonce`     | `string`                                                     | -        | Optional server-generated nonce bound into the `id_token`                   |\n| `onAuth`    | `(result: TelegramLoginSuccess) => void`                     | -        | Success callback with `id_token` and decoded `user`                         |\n| `onError`   | `(error: string) => void`                                    | -        | Error callback                                                              |\n| `autoInit`  | `boolean`                                                    | `true`   | Load script and call `Telegram.Login.init` on mount                         |\n| `disabled`  | `boolean`                                                    | `false`  | Extra disabled flag                                                         |\n| `className` | `string`                                                     | -        | CSS class for the default `<button>`                                        |\n| `children`  | `React.ReactNode`                                            | -        | Custom label, or a single element cloned with `onClick` / `disabled`        |\n\n`TelegramLoginSuccess`: `{ id_token: string; user: TelegramLoginUser }`.\n\nAlways verify `id_token` on your server. This package does not include server helpers.\n\n### TelegramLegacyLoginWidget Props\n\n| Prop            | Type                                         | Default      | Description                                                                    |\n| --------------- | -------------------------------------------- | ------------ | ------------------------------------------------------------------------------ |\n| `botName`       | `string`                                     | **required** | Bot username used for authorization (without `@`)                              |\n| `size`          | `\"large\" \\| \"medium\" \\| \"small\"`             | -            | Button size (`data-size`). Telegram uses large when omitted                    |\n| `userpic`       | `boolean`                                    | `true`       | Whether to show the user avatar. When `false`, sets `data-userpic=\"false\"`     |\n| `radius`        | `number`                                     | -            | Corner radius of the button in pixels                                          |\n| `requestAccess` | `boolean`                                    | `false`      | When `true`, requests write access (`data-request-access=\"write\"`)             |\n| `authUrl`       | `string`                                     | -            | Redirect URL after authorization (`data-auth-url`)                             |\n| `onAuth`        | `(data: TelegramLegacyLoginData) => void`    | -            | Callback with user data after successful authorization                         |\n| `className`     | `string`                                     | -            | Optional CSS class for the container                                           |\n| `onError`       | `(e: unknown) => void`                       | -            | Callback when an error occurs                                                  |\n| `onLoad`        | `() => void`                                 | -            | Callback when the widget loads successfully                                    |\n\n`TelegramLegacyLoginData` fields: `id`, `first_name?`, `last_name?`, `username?`, `photo_url?`, `auth_date`, `hash`.\n\n### TelegramShareWidget Props\n\n| Prop        | Type                             | Default      | Description                                      |\n| ----------- | -------------------------------- | ------------ | ------------------------------------------------ |\n| `url`       | `string`                         | **required** | Absolute URL to share                            |\n| `comment`   | `string`                         | -            | Optional comment included with the shared link   |\n| `size`      | `\"large\" \\| \"medium\" \\| \"small\"` | -            | Button size                                      |\n| `className` | `string`                         | -            | Optional CSS class for the container             |\n| `onError`   | `(e: unknown) => void`           | -            | Callback when an error occurs                    |\n| `onLoad`    | `() => void`                     | -            | Callback when the widget loads successfully      |\n\n## Examples\n\n### Basic Usage\n\n```tsx\nimport {\n  TelegramPostWidget,\n  TelegramDiscussionWidget,\n  TelegramLoginWidget,\n  TelegramShareWidget,\n} from '@baranov-guru/react-telegram-widgets';\n\nfunction BlogPost() {\n  return (\n    <article>\n      <h1>My Article</h1>\n      <p>Article content...</p>\n\n      <TelegramShareWidget\n        url='https://example.com/my-article'\n        comment='Read this article'\n      />\n\n      <TelegramPostWidget\n        post='baranov_guru/1'\n        width='100%'\n        dark={true}\n      />\n\n      <h2>Comments</h2>\n      <TelegramDiscussionWidget\n        discussion='baranov_guru'\n        commentsLimit={20}\n        height={500}\n        colorful={true}\n      />\n\n      <h2>Sign in</h2>\n      <TelegramLoginWidget\n        clientId={123456789}\n        scope={['profile']}\n        onAuth={result => console.log(result.id_token, result.user)}\n      />\n    </article>\n  );\n}\n```\n\n### Server-side verification\n\nThese snippets are **documentation examples only** — they are not exported from this package. Always verify Telegram credentials on your backend.\n\n#### OIDC `id_token` (recommended)\n\nVerify the JWT with Telegram's JWKS. Example using [`jose`](https://github.com/panva/jose):\n\n```ts\nimport { createRemoteJWKSet, jwtVerify } from 'jose';\n\nconst JWKS = createRemoteJWKSet(\n  new URL('https://oauth.telegram.org/.well-known/jwks.json')\n);\n\nexport async function verifyTelegramIdToken(\n  idToken: string,\n  clientId: number,\n  expectedNonce?: string\n) {\n  const { payload } = await jwtVerify(idToken, JWKS, {\n    issuer: 'https://oauth.telegram.org',\n    audience: String(clientId),\n  });\n\n  if (expectedNonce && payload.nonce !== expectedNonce) {\n    throw new Error('Invalid nonce');\n  }\n\n  return payload;\n}\n\n// Example Express-style handler\napp.post('/api/auth/telegram', async (req, res) => {\n  const { id_token } = req.body;\n  const claims = await verifyTelegramIdToken(\n    id_token,\n    Number(process.env.TELEGRAM_CLIENT_ID),\n    req.session.telegramNonce // if you issued a nonce\n  );\n  // create your session from claims.id / claims.sub\n  res.json({ ok: true, userId: claims.id ?? claims.sub });\n});\n```\n\nSee the official [Log In With Telegram](https://core.telegram.org/widgets/login) docs for claim details. For full redirect-based OIDC (authorization code + PKCE), use Telegram as a standard OIDC provider — that flow is outside this React package.\n\n#### Legacy `hash`\n\n```ts\nimport { createHash, createHmac, timingSafeEqual } from 'node:crypto';\nimport type { TelegramLegacyLoginData } from '@baranov-guru/react-telegram-widgets';\n\nexport function verifyTelegramLegacyLogin(\n  data: TelegramLegacyLoginData,\n  botToken: string,\n  maxAgeSeconds = 86400\n) {\n  const { hash, ...fields } = data;\n  const checkString = Object.keys(fields)\n    .sort()\n    .map(key => `${key}=${(fields as Record<string, unknown>)[key]}`)\n    .join('\\n');\n\n  const secretKey = createHash('sha256').update(botToken).digest();\n  const computed = createHmac('sha256', secretKey)\n    .update(checkString)\n    .digest('hex');\n\n  const a = Buffer.from(computed, 'hex');\n  const b = Buffer.from(hash, 'hex');\n  if (a.length !== b.length || !timingSafeEqual(a, b)) {\n    throw new Error('Invalid Telegram login hash');\n  }\n\n  const now = Math.floor(Date.now() / 1000);\n  if (now - data.auth_date > maxAgeSeconds) {\n    throw new Error('Telegram login data is too old');\n  }\n\n  return data;\n}\n```\n\nNever put the bot token or Client Secret in client-side code.\n\n### With Error Handling\n\n```tsx\nimport { TelegramPostWidget } from '@baranov-guru/react-telegram-widgets';\n\nfunction SafeTelegramWidget() {\n  const handleError = (error: unknown) => {\n    console.error('Telegram widget error:', error);\n    // Show fallback content or error message\n  };\n\n  const handleSuccess = () => {\n    console.log('Telegram widget loaded successfully');\n  };\n\n  return (\n    <TelegramPostWidget\n      post='baranov_guru/61'\n      onError={handleError}\n      onLoad={handleSuccess}\n    />\n  );\n}\n```\n\n### Custom Styling\n\n```tsx\nimport { TelegramDiscussionWidget } from '@baranov-guru/react-telegram-widgets';\n\nfunction CustomComments() {\n  return (\n    <TelegramDiscussionWidget\n      discussion='baranov_guru/61'\n      commentsLimit={15}\n      height={600}\n      color='#4a90e2'\n      colorful={true}\n      dark={true}\n      className='my-custom-comments-widget'\n    />\n  );\n}\n```\n\n## TypeScript Support\n\nThe package includes full TypeScript support with exported types:\n\n```tsx\nimport {\n  TelegramPostWidget,\n  TelegramPostWidgetProps,\n  TelegramDiscussionWidget,\n  TelegramDiscussionWidgetProps,\n  TelegramLoginWidget,\n  TelegramLoginWidgetProps,\n  TelegramLoginSuccess,\n  TelegramLegacyLoginWidget,\n  TelegramLegacyLoginWidgetProps,\n  TelegramLegacyLoginData,\n  TelegramShareWidget,\n  TelegramShareWidgetProps,\n  useTelegramLogin,\n} from '@baranov-guru/react-telegram-widgets';\n\nconst MyComponent: React.FC<TelegramPostWidgetProps> = props => {\n  return <TelegramPostWidget {...props} />;\n};\n\nconst handleAuth = (result: TelegramLoginSuccess) => {\n  // forward result.id_token to your API\n};\n\nconst handleLegacyAuth = (user: TelegramLegacyLoginData) => {\n  // forward user (with hash) to your API\n};\n```\n\n## Requirements\n\n- React 16.8.0 or higher\n- React DOM 16.8.0 or higher\n\n## Browser Support\n\nThis package uses the official Telegram Widget API, which supports all modern browsers.\n\n## Author\n\n**Alexey Baranov (Nejivoi)**\n\n- GitHub: [@Nejivoi](https://github.com/Nejivoi)\n- Website: [baranov.guru](https://baranov.guru)\n\n## Support the Author\n\nIf you find this package helpful and would like to support its development, please consider:\n\n[![Support the Author](https://img.shields.io/badge/Support%20the%20Author-FF6B6B?style=for-the-badge&logo=heart&logoColor=white)](https://baranov.guru/support/)\n\nYour support helps maintain and improve this package! ❤️\n\n## License\n\nMIT\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## Publishing\n\nThis package publishes from GitHub Actions via **npm Trusted Publishing (OIDC)**.\nNo long-lived `NPM_TOKEN` is required for publish.\n\n1. **Trusted Publisher** (one-time, on npmjs.com):\n   - Open `@baranov-guru/react-telegram-widgets` → **Settings** → **Trusted Publisher**\n   - Repository: `baranov-guru/react-telegram-widgets`\n   - Workflow filename: `publish.yml` (must match `.github/workflows/publish.yml` exactly)\n\n2. **Bump version and create a Release**:\n   - Update `version` in `package.json` (e.g. `npm version minor`) and push\n   - Create a GitHub Release tagged with the same version (e.g. `v1.1.0`)\n   - Workflow: lint → test → build → `npm publish` with provenance via OIDC\n\nIf publish fails with `404` / `ENEEDAUTH` while Trusted Publisher is configured, check\nNode/npm version in the workflow (need npm ≥ 11.5.1), that `NODE_AUTH_TOKEN` is **not**\nset on the publish step, and that the Trusted Publisher workflow name matches exactly.\n\n### Manual Publishing\n\nFor a one-off local publish (logged in as the package owner):\n\n```bash\nnpm run build\nnpm publish --access public\n```\n\n### Re-running a failed release\n\nAfter fixing the workflow or Trusted Publisher config, re-run the failed\n**Publish Package** job from the Actions tab. Do **not** bump the version again if\nthat version never landed on npm.\n## Development\n\n```bash\n# Install dependencies\nnpm install\n\n# Run tests\nnpm test\n\n# Run tests with coverage\nnpm run test:coverage\n\n# Build package\nnpm run build\n\n# Watch mode for development\nnpm run dev\n\n# Lint code\nnpm run lint\n\n# Fix linting issues\nnpm run lint:fix\n\n# Format code\nnpm run format\n\n# Check code formatting\nnpm run format:check\n\n# Run all checks (lint, format, test)\nnpm run check\n```\n","readmeFilename":"README.md"}