{"id":40394003,"url":"https://github.com/pockettogether/pocket-chat","last_synced_at":"2026-03-11T08:29:46.696Z","repository":{"id":323123445,"uuid":"1092128275","full_name":"PocketTogether/pocket-chat","owner":"PocketTogether","description":"A real-time chat platform built with PocketBase and Vue3 | 一个基于 PocketBase 与 Vue3 的实时聊天平台","archived":false,"fork":false,"pushed_at":"2026-01-11T15:39:05.000Z","size":23179,"stargazers_count":8,"open_issues_count":0,"forks_count":1,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-01-11T18:05:25.197Z","etag":null,"topics":["chat","docker","pocketbase","tailwindcss","tanstack-query","typescript","vue3"],"latest_commit_sha":null,"homepage":"https://sakiko.top","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/PocketTogether.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-11-08T03:36:42.000Z","updated_at":"2026-01-11T15:14:13.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/PocketTogether/pocket-chat","commit_stats":null,"previous_names":["haruki1953/pocket-chat","pockettogether/pocket-chat"],"tags_count":9,"template":false,"template_full_name":null,"purl":"pkg:github/PocketTogether/pocket-chat","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PocketTogether%2Fpocket-chat","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PocketTogether%2Fpocket-chat/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PocketTogether%2Fpocket-chat/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PocketTogether%2Fpocket-chat/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/PocketTogether","download_url":"https://codeload.github.com/PocketTogether/pocket-chat/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/PocketTogether%2Fpocket-chat/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28603402,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-20T12:01:53.233Z","status":"ssl_error","status_checked_at":"2026-01-20T12:01:46.545Z","response_time":117,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["chat","docker","pocketbase","tailwindcss","tanstack-query","typescript","vue3"],"created_at":"2026-01-20T13:00:29.866Z","updated_at":"2026-01-20T13:00:50.031Z","avatar_url":"https://github.com/PocketTogether.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n  \u003cimg src=\"./assets/message-3-fill-7899CC.svg\" style=\"width: 128px; height: 128px;\"\u003e\n\u003c/div\u003e\n\n\u003ch1 align=\"center\"\u003e\n  PocketChat\n\u003c/h1\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003c!-- Vue.js --\u003e\n  \u003ca href=\"https://vuejs.org/\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/badge/Vue.js-4FC08D?style=for-the-badge\u0026logo=vue.js\u0026logoColor=white\" alt=\"Vue.js\"\u003e\u003c/a\u003e\n  \u003c!-- TailwindCSS --\u003e\n  \u003ca href=\"https://tailwindcss.com/\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/badge/TailwindCSS-38B2AC?style=for-the-badge\u0026logo=tailwindcss\u0026logoColor=white\" alt=\"TailwindCSS\"\u003e\u003c/a\u003e\n  \u003c!-- TanStack Query --\u003e\n  \u003ca href=\"https://tanstack.com/query/latest\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/badge/TanStack%20Query-FF4154?style=for-the-badge\u0026logo=TanStack\u0026logoColor=white\" alt=\"TanStack Query\"\u003e\u003c/a\u003e\n  \u003c!-- PocketBase --\u003e\n  \u003ca href=\"https://pocketbase.io/\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/badge/PocketBase-0E83CD?style=for-the-badge\u0026logo=pocketbase\u0026logoColor=white\" alt=\"PocketBase\"\u003e\u003c/a\u003e\n  \u003c/br\u003e\n  \u003c!-- License --\u003e\n  \u003ca href=\"https://opensource.org/licenses/MIT\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/badge/License-MIT-green.svg?style=for-the-badge\" alt=\"MIT License\"\u003e\u003c/a\u003e\n  \u003c!-- GitHub Release --\u003e\n  \u003ca href=\"https://github.com/PocketTogether/pocket-chat/releases\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/github/release/PocketTogether/pocket-chat.svg?style=for-the-badge\" alt=\"GitHub Release\"\u003e\u003c/a\u003e\n  \u003c!-- GitHub Activity --\u003e\n  \u003ca href=\"https://github.com/PocketTogether/pocket-chat/commits\" target=\"_blank\"\u003e\u003cimg src=\"https://img.shields.io/github/commit-activity/m/PocketTogether/pocket-chat.svg?style=for-the-badge\" alt=\"GitHub Activity\"\u003e\u003c/a\u003e\n  \u003c/br\u003e\n  \u003c!-- Discord --\u003e\n  \u003ca href=\"https://discord.gg/aZq6u3Asak\"\u003e\u003cimg alt=\"Discord\" src=\"https://img.shields.io/discord/1192346949635026944?logo=discord\u0026logoColor=white\u0026label=Discord\u0026color=4285F4\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n  \u003c!-- Telegram --\u003e\n  \u003ca href=\"https://t.me/PocketTogether\"\u003e\u003cimg alt=\"Telegram\" src=\"https://img.shields.io/badge/Telegram-JOIN-188FCA.svg?logo=telegram\u0026logoColor=white\u0026style=for-the-badge\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  English | \u003ca href=\"./README_CN.md\"\u003e简体中文\u003c/a\u003e\n\u003c/p\u003e\n\n- PocketChat is an open-source real-time chat platform built on [PocketBase](https://github.com/pocketbase/pocketbase) and [Vue3](https://github.com/vuejs/vue).\n- Cross-platform support for Linux, Windows, and macOS. Easy deployment: can be run on Windows after extraction. Supports Docker deployment.\n- Supports GitHub, X/Twitter, and other OAuth2 login/registration methods.\n- Supports message reply, edit, delete, and jumping to a message via its link.\n- Supports in-site new message notifications and desktop new message notifications.\n- Supports image sending, image viewing, and image metadata editing\n- Supports file sending, file downloading, and file metadata editing.\n- Supports user permission control: message sending permission, image upload permission, file upload permission, and user banning.\n- Supports PWA installation, including “Install App” or “Add to Home Screen”, and provides partial offline access.\n- Project address: https://github.com/PocketTogether/pocket-chat\n- Live demo: https://sakiko.top\n\n![](./assets/Snipaste_2025-11-16_16-03-05.png)\n![](./assets/Snipaste_2026-01-18_17-30-48.png)\n\n\u003cdetails\u003e\n\u003csummary\u003e📸 \u003cb\u003eMore Screenshots\u003c/b\u003e\u003c/summary\u003e\n\n![](./assets/Snipaste_2026-01-18_16-31-41.png)\n![](./assets/Snipaste_2026-01-05_10-33-05.jpg)\n![](./assets/Snipaste_2026-01-05_10-34-08.jpg)\n![](./assets/Snipaste_2026-01-05_10-11-45.jpg)\n![](./assets/Snipaste_2025-11-16_16-00-27.png)\n![](./assets/Snipaste_2025-11-26_19-39-09.png)\n![](./assets/Snipaste_2025-11-26_19-30-04.png)\n![](./assets/Snipaste_2026-01-20_18-06-50.png)\n![](./assets/Snipaste_2026-01-20_15-58-20.jpg)\n![](./assets/Snipaste_2026-01-20_15-59-39.jpg)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e💡 \u003cb\u003eDevelopment Plan\u003c/b\u003e\u003c/summary\u003e\n\n- User list and online status display\n- User @ mention functionality\n- Voice sending functionality\n\n\u003c/details\u003e\n\n## Deployment\n\nBefore deploying on Linux, it is recommended to try it first on Windows to get familiar with PocketChat.\n\nSince version v0.1.0, [Docker deployment](#deploy-with-docker) has been supported.\n\n### Quick Start on Windows\n\nAll PocketChat releases are published on GitHub. Download the latest zip package from https://github.com/PocketTogether/pocket-chat/releases, for example `pocket_chat_0.0.1_windows_amd64.zip`.\n\n![](./assets/image.png)\n\nExtract the archive and double-click `start.bat`. A command-line window will open.\n\n![](./assets/image-1.png)\n\nAt the same time, your browser will automatically open the PocketBase superuser creation page (the link shown in the console, e.g. `http://127.0.0.1:58090/_/#/pbinstal/eyJhbGciOiJI......`).\n\nCreating a superuser is a [**required step after deployment**](#required-post-deployment-steps). See [Create admin superuser using the link from the logs](#create-admin-superuser-using-the-link-from-the-logs).\n\n![](./assets/image-3.png)\n\n`http://127.0.0.1:58090/_/` → PocketChat admin panel (accessible after creating the superuser)\n\n- `users` collection: can view all users and modify user permissions.  \n  See [users collection – user permission control](#users-collection--user-permission-control) (supported since `v0.3.0`)\n- `config` collection: project-specific settings (see [Config collection settings](#config-collection-settings))\n- `messages` collection: view all sent messages\n- `images` collection: view all uploaded images (supported since version `v0.2.0`).\n- `files` collection: view all uploaded files (supported since version `v0.4.0`).\n\n![](./assets/image-4.png)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003eimages collection v0.2.0\u003c/b\u003e\u003c/summary\u003e\n\n![](./assets/Snipaste_2026-01-05_10-50-02.png)\n\n\u003c/details\u003e\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cb\u003efiles collection v0.4.0\u003c/b\u003e\u003c/summary\u003e\n\n![](./assets/Snipaste_2026-01-18_16-35-24.png)\n\n\u003c/details\u003e\n\n`http://127.0.0.1:58090` → PocketChat main chat interface\n\n![](./assets/image-2.png)\n\nContinue reading this document for more configuration options.\n\n### Full Deployment on Linux\n\nFor clarity, this guide uses the [1Panel](https://github.com/1Panel-dev/1Panel) control panel.\n\n#### Prepare the website\n\n- Prepare a domain name (example used here: `uika.top`)\n- Create a reverse proxy in 1Panel (OpenResty) pointing to `http://127.0.0.1:58090`\n\n![](./assets/Snipaste_2025-11-17_09-01-57.png)\n\n\u003e In this example the port is 58091 because 58090 was already in use by another PocketChat instance. How to change the port is explained in [Change port (optional)](#change-port-optional)\n\nAfter creating the proxy, enable HTTPS (refer to 1Panel docs: https://docs.1panel.pro/user_manual/websites/website_config_basic/#https)\n\nFor configuring browser caching in the reverse proxy, see\n[Configuring Browser Caching in the Reverse Proxy](#configuring-browser-caching-in-the-reverse-proxy)\n\n#### Download and extract\n\nIn 1Panel File Manager, create a folder (e.g. `/root/pocketchat`), then use `Download from remote` to fetch the Linux zip from GitHub Releases (e.g. `pocket_chat_0.0.1_linux_amd64.zip`).\n\n![](./assets/Snipaste_2025-11-17_09-30-20.png)\n\nAfter downloading, extract it.\n\n![](./assets/Snipaste_2025-11-17_09-36-50.png)\n\n#### Set executable permission\n\nClick the permission number next to the `pocketbase` file and make it executable.\n\n![](./assets/Snipaste_2025-11-17_13-33-57.png)\n\n#### Change port (optional)\n\nEdit `start.sh` and change the port in the last line:\n\n```sh\n./pocketbase serve --http 127.0.0.1:58090   # Change 58090 to your desired port\n```\n\n#### Run in background \u0026 start on boot\n\nIn `/etc/systemd/system`, create a file named `pocketchat.service` with the following content (adjust paths as needed):\n\n```ini\n[Unit]\nDescription=PocketChat Service\nAfter=network.target\n\n[Service]\nType=simple\nWorkingDirectory=/root/pocketchat\nExecStart=/bin/sh /root/pocketchat/start.sh\nRestart=always\nUser=root\n\n[Install]\nWantedBy=multi-user.target\n```\n\n![](./assets/collage.png)\n\nThen open the terminal in 1Panel and run:\n\n```sh\n# Reload systemd configuration\nsystemctl daemon-reload\n# Start the service\nsystemctl start pocketchat\n# Enable on boot\nsystemctl enable pocketchat\n# View logs\njournalctl -u pocketchat.service --no-pager -o cat\n```\n\n![](./assets/Snipaste_2025-11-17_14-15-28.png)\n\nReplace `127.0.0.1:58091` in the log link with your domain and change `http` → `https`. Example:\n\n```\nhttp://127.0.0.1:58091/_/#/pbinstal/eyJhbGcixxxxxxxxxxx......xxxxxxxxxxxxxx\n\nhttps://uika.top/_/#/pbinstal/eyJhbGcixxxxxxxxxxx......xxxxxxxxxxxxxx\n```\n\nOpen the modified link, [create the superuser](#create-admin-superuser-using-the-link-from-the-logs), and complete the [**required post-deployment steps**](#required-post-deployment-steps).\n\n![](./assets/Snipaste_2025-11-17_14-50-28.png)\n![](./assets/Snipaste_2025-11-17_15-12-46.png)\n\nAdditional useful commands:\n\n```sh\n# Check status\nsystemctl status pocketchat\n# Restart\nsystemctl restart pocketchat\n# Stop\nsystemctl stop pocketchat\n# Disable boot start\nsystemctl disable pocketchat\n```\n\n### Deploy with Docker\n\nYou can find the latest image at: https://github.com/PocketTogether/pocket-chat/pkgs/container/pocket-chat\n\n```sh\nmkdir -p ${HOME}/PocketChat/pb_data\ncd ${HOME}/PocketChat\n\ndocker run -d \\\n  --name PocketChat \\\n  -v ${HOME}/PocketChat/pb_data:/app/pb_data \\\n  -p 58090:58090 \\\n  --restart unless-stopped \\\n  ghcr.io/PocketTogether/pocket-chat:latest\n\ndocker logs PocketChat\n```\n\n\n### PocketChat Update Guide (For Deployed Instances)\n\n#### Manual Update Guide\n\nThe following steps apply to **PocketChat deployed via binary (non-Docker)**. All operations can be performed through **1Panel**.\n\n##### 1. Stop the currently running service\n```sh\nsystemctl stop pocketchat\n```\n\n##### 2. Navigate to the PocketChat installation directory\nThis is usually the directory where you originally extracted the files, for example:\n```sh\ncd /root/pocketchat\n```\n\n##### 3. Back up the existing version (optional but recommended)\nTo prevent data loss in case the update fails, you can zip the current directory as a backup.\n\n##### 4. Remove old version files (keep `pb_data`)\nDelete all files and folders **except** `pb_data`.\n\n\u003e `pb_data` is the PocketBase database directory and **must be preserved**.\n\n##### 5. Download and extract the new PocketChat release\nDownload the latest PocketChat release from GitHub Releases and extract it, for example:\n`pocket_chat_0.2.1_linux_amd64.zip`\n```\npocket_chat_\u003cVERSION\u003e_linux_amd64.zip\n```\n\n##### 6. Important notes\n- **If you changed the port**\n  Update the port in `start.sh`:\n  ```sh\n  ./pocketbase serve --http 127.0.0.1:58090\n  ```\n\n- **If you modified frontend files**  \n  (e.g., `pb_public/index.html`)  \n  Reapply your custom changes after updating.\n\n- **Ensure the `pocketbase` binary has executable permissions**\n\n##### 7. Start the service and check its status\nStart the service:\n```sh\nsystemctl start pocketchat\n```\n\nCheck the service status:\n```sh\nsystemctl status pocketchat\n```\n\nIf the status is normal, the update is complete.\n\n#### Docker Deployment Update Guide\n\nIf you deployed PocketChat using Docker, the update process is simpler.\n\n##### 1. Check the latest available image versions\nVisit:  \nhttps://github.com/PocketTogether/pocket-chat/pkgs/container/pocket-chat\n\nChoose the version you want to update to, for example:\n`ghcr.io/PocketTogether/pocket-chat:0.2.1`\n```\nghcr.io/PocketTogether/pocket-chat:\u003cVERSION\u003e\n```\n\n(Optional) Pull the image in advance:\n```sh\ndocker pull ghcr.io/PocketTogether/pocket-chat:\u003cVERSION\u003e\n```\n\nBenefits of pulling beforehand:\n- You can clearly see the download progress.\n- Avoids container creation failure if the pull fails during `docker run`.\n- Cleaner separation of pull/run steps in CI/CD workflows.\n\n##### 2. Stop and remove the old container (data will not be deleted)\n```sh\ndocker stop PocketChat\ndocker rm PocketChat\n```\n\n\u003e Your data is stored in the mounted directory `${HOME}/PocketChat/pb_data` and will not be lost.\n\n##### 3. Start a new container using the latest image\n```sh\ndocker run -d \\\n  --name PocketChat \\\n  -v ${HOME}/PocketChat/pb_data:/app/pb_data \\\n  -p 58090:58090 \\\n  --restart unless-stopped \\\n  ghcr.io/PocketTogether/pocket-chat:\u003cVERSION\u003e\n```\n\n##### 4. Check logs to confirm everything is running correctly\n```sh\ndocker logs PocketChat\n```\n\nUpdate complete.\n\n## Required Post-Deployment Steps\n\n### Create admin superuser using the link from the logs\n\nFill in email and password. The email does not need to be real (e.g. `admin@admin.test`).\n\n\u003e [`.test` is a reserved top-level domain that will never be registered on the public internet - Wikipedia](https://en.wikipedia.org/wiki/.test)\n\n![](./assets/Snipaste_2025-11-17_14-50-28.png)\n\n### Config collection settings\n\n\u003c!-- ![](./assets/Snipaste_2025-11-17_15-30-28.png) --\u003e\n\u003c!-- ![](./assets/Snipaste_2026-01-05_10-56-53.png) --\u003e\n![](./assets/Snipaste_2026-01-11_18-35-25.png)\n\n- `website-name` – Site name displayed on login page and top-left of chat\n\n- [`external-links-to-social-media-icons-etc`](#social-media-and-other-icon-external-links-external-links-to-social-media-icons-etc) – Social media icon links shown at the bottom of the login page\n\n- [`admin-contact-info-for-permission`](#admin-contact-info-for-permission) : Administrator contact information, mainly used to display to users when they lack permissions (supported since `v0.3.0`)\n\n- [`upload-image-process-options`](#image-processing-configuration-upload-image-process-options) – Image processing configuration `v0.2.0`\n\n- `password-update-rate-limit-second` – Seconds to wait before another password change request is allowed\n\n- `email-verify-rate-limit-second` – Seconds to wait before another email verification request is allowed\n\n- `email-update-rate-limit-second` – Seconds to wait before another email update request is allowed\n\n- `allow-anonymous-view` – `true` = guests can view chat; `false` = only logged-in users\n\n- `allow-users-to-register` – `true` = registration enabled; `false` = registration disabled and form hidden\n\n- `user-register-oauth2-only` : Whether to allow OAuth2-only registration. Default value: `false` (supported since `v0.3.0`)\n  - When `true`, only OAuth2 registration is allowed. Email-password registration is disabled, and the registration form will not appear on the login page.\n  - When `false`, both OAuth2 registration and email-password registration are allowed.\n  - Note: When `allow-users-to-register` is `false`, registration is completely disabled, and `user-register-oauth2-only` does not take effect.\n\n- `user-can-send-message-default` : Whether sending messages is allowed by default. Default value: `true` (supported since `v0.3.0`)\n  - Controls the system’s default message-sending permission when the `canSendMessage` field in the users collection is not set.  \n    This configuration only applies when the user record does not explicitly specify `\"YES\"` or `\"NO\"`.  \n    See [users collection – user permission control](#users-collection--user-permission-control)\n  - `true`: When `canSendMessage` is not set, the user is allowed to send messages by default.\n  - `false`: When `canSendMessage` is not set, the user is not allowed to send messages by default.\n\n- `user-can-upload-image-default` : Whether uploading images is allowed by default. Default value: `true` (supported since `v0.3.0`)\n  - Same behavior as `user-can-send-message-default`.\n  - `true`: When `canUploadImage` is not set, the user is allowed to upload images by default.\n  - `false`: When `canUploadImage` is not set, the user is not allowed to upload images by default.\n\n- `user-can-upload-file-default` : Whether uploading files is allowed by default. Default value: `true` (supported since `v0.4.0`)\n  - Same behavior as `user-can-upload-image-default`.\n  - `true`: When `canUploadFile` is not set, the user is allowed to upload files by default.\n  - `false`: When `canUploadFile` is not set, the user is not allowed to upload files by default.\n\n- `user-max-upload-file-size-default` : Default maximum file upload size (in bytes). Default value: `20971520` (`20 * 1024 * 1024`), which equals 20MB (supported since `v0.4.0`)\n  - Used when a user’s `maxUploadFileSize` field is set to `0`, determining the default maximum file size the user is allowed to upload.\n  - Must be a positive integer (greater than 0), measured in bytes.\n  - Note that both `maxUploadFileSize` and `user-max-upload-file-size-default` only provide data for the frontend to enforce size limits. The actual file size restriction is handled on the frontend. See  \n    [users collection — permission control: maxUploadFileSize](#maxuploadfilesize)\n\n\n#### Social media and other icon external links (external-links-to-social-media-icons-etc)\n\n![](./assets/Snipaste_2025-11-17_15-47-40.png)\n\nDefault value:\n\n```json\n[\n  {\n    \"icon\": \"ri-github-line\",\n    \"link\": \"https://github.com/PocketTogether/pocket-chat\",\n    \"name\": \"github\"\n  },\n  {\n    \"icon\": \"ri-discord-line\",\n    \"link\": \"https://discord.gg/aZq6u3Asak\",\n    \"name\": \"discord\"\n  },\n  {\n    \"icon\": \"ri-telegram-2-line\",\n    \"link\": \"https://t.me/PocketTogether\",\n    \"name\": \"telegram\"\n  }\n]\n```\n\nSet to `[]` to disable. \n\nIcons come from https://remixicon.com/ (use the class name).\n\n![](./assets/Snipaste_2025-11-17_15-50-13.png)\n\n### admin-contact-info-for-permission\n\nDefault value: empty string `\"\"`\n\nRecommended text (use `\\n` for line breaks):\n\n```\n\"Discord - discord.gg/aZq6u3Asak\\nTelegram - t.me/PocketTogether\"\n```\n\nDisplayed in the frontend as:\n\n![](./assets/Snipaste_2026-01-11_19-19-53.jpg)\n\n\n#### Image processing configuration (upload-image-process-options)\n\n![](./assets/Snipaste_2026-01-05_11-23-48.png)\n\nDefault value:\n\n```json\n{\n  \"bigConfig\": {\n    \"format\": \"image/webp\",\n    \"quality\": 0.9,\n    \"sumWidthHeightLimit\": 4000\n  },\n  \"imageConfig\": {\n    \"format\": \"image/webp\",\n    \"quality\": 0.8,\n    \"sumWidthHeightLimit\": 2000\n  },\n  \"smallConfig\": {\n    \"format\": \"image/webp\",\n    \"quality\": 0.8,\n    \"sumWidthHeightLimit\": 1200\n  },\n  \"tinyConfig\": {\n    \"format\": \"image/webp\",\n    \"quality\": 0.8,\n    \"sumWidthHeightLimit\": 800\n  }\n}\n```\n\nConfiguration details:\n\n```\nbigConfig   Configuration for large images\nimageConfig Configuration for medium images\nsmallConfig Configuration for small images\ntinyConfig  Configuration for extra-small images\n\nformat  Image format, supported values:\n        \"image/png\" | \"image/jpeg\" | \"image/webp\"\n\nquality Image quality, a number between 0 and 1.\n        Only applies to \"image/jpeg\" and \"image/webp\".\n\nsumWidthHeightLimit\n        The limit for the sum of image width and height.\n        Images will be resized according to this value.\n        Note: The values must follow the order:\n              bigConfig \u003e imageConfig \u003e smallConfig \u003e tinyConfig\n\n(The frontend will automatically choose the most appropriate image size\nbased on element dimensions and screen resolution.)\n```\n\n#### Reset config to defaults\n\nDelete any field in the config collection and restart PocketChat – that field will revert to its default value.\n\n#### Config Validatio\n\nAfter modifying the `config` collection, reopen the frontend webpage (note: this refers to the user-facing site at the root path, **not** the PocketBase admin panel). Then open the browser’s developer tools and check the console.  \nIf no error messages appear, the configuration is valid.\n\nIf a configuration entry is missing — for example, if `external-links-to-social-media-icons-etc` is not found — the following error will appear:\n\n```\nsrc\\queries\\pb-collection-config.ts\nusePbCollectionConfigQuery\nfindKeyItem == null\nkey: external-links-to-social-media-icons-etc\n```\n\nIf a configuration entry is invalid — for example, if the type of `upload-image-process-options` is incorrect — the following error will appear:\n\n```\nsrc\\queries\\pb-collection-config.ts\nusePbCollectionConfigQuery\nfindKeyItemParseResult.success === false\nkey: upload-image-process-options\n```\n\n![](./assets/Snipaste_2026-01-05_13-30-55.png)\n\n### users collection – user permission control\n\n\u003c!-- ![](./assets/Snipaste_2026-01-11_19-27-16.png) --\u003e\n![](./assets/Snipaste_2026-01-18_18-22-51.png)\n\n#### canSendMessage\nUsed to control whether the user has permission to send messages.  \n- Field type: **select**, options:\n- `\"YES\"`: Explicitly allow the user to send messages  \n- `\"NO\"`: Explicitly forbid the user from sending messages  \n- `N/A` (default): Not set. The system will use  \n  **user-can-send-message-default** from the config collection.\n\n#### canUploadImage\nUsed to control whether the user has permission to upload images.  \n- Field type: **select**, options:\n- `\"YES\"`: Explicitly allow the user to upload images  \n- `\"NO\"`: Explicitly forbid the user from uploading images  \n- `N/A` (default): Not set. The system will use  \n  **user-can-upload-image-default** from the config collection.\n\n#### canUploadFile\nUsed to control whether the user has permission to upload files.  \n- Field type: **select**, options:  \n- `\"YES\"`: Explicitly allow the user to upload files  \n- `\"NO\"`: Explicitly forbid the user from uploading files  \n- `N/A` (default): Not set. The system will use  \n  **user-can-upload-file-default** from the config collection.\n\n#### maxUploadFileSize\nUsed to control the maximum file size (in bytes) the user is allowed to upload.  \n- Field type: **number**, must be an integer greater than or equal to `0`  \n- `\u003e 0`: Explicitly specifies the maximum upload file size (in bytes) for this user  \n- `0` (default): Not set. The system will use  \n  **user-max-upload-file-size-default** from the config collection.\n\nAdditional notes:  \n- `maxUploadFileSize` and `user-max-upload-file-size-default` are **only used for frontend-side size enforcement**, because PocketBase currently does not support file size limits in API rules.  \n- Permissions such as `canUploadFile`, however, are fully enforceable on both the frontend and backend (via PocketBase API rules).\n\nIf you want to enforce a backend-level file size limit (this limit applies globally to all users), you can modify the `Max file size` option in the **files** collection → **file** field settings.  \nMake sure to save the collection after making changes.\n\n![](./assets/Snipaste_2026-01-18_18-28-45.png)\n\n#### isBanned\nUsed to mark whether a user is banned.  \n- Field type: **boolean**  \n- **false** (default): User is normal and can log in and use all features  \n- **true**: User is banned and cannot access any content\n\nBan effect:  \n![](./assets/Snipaste_2026-01-11_19-37-25.png)\n\n### Application settings\n\n![](./assets/Snipaste_2025-11-17_16-30-18.png)\n\n- **Application name** – used as sender name in emails (keep consistent with `website-name`)\n- **Application URL** – used in emails, set to your domain\n\nIf using Cloudflare, add `CF-Connecting-IP` to **User IP proxy headers** to resolve real IPs.\n\n![](./assets/Snipaste_2025-11-17_16-53-57.png)\n![](./assets/Snipaste_2025-11-17_16-57-00.png)\n\nSee PocketBase production recommendations: https://pocketbase.io/docs/going-to-production/\n\n### pb_public/index.html – site meta information\n\nUsed for social media previews. Edit `pb_public/index.html` as needed.\n\n![](./assets/Snipaste_2025-11-17_17-35-37.png)\n\nThe loading animation is also defined here.\n\n## Configure email sending (SMTP)\n\nRequired for email verification, password reset, etc.\n\nExample configuration used on sakiko.top:\n\n![](./assets/Snipaste_2025-11-17_17-06-11.png)\n\nSelf-hosted option: https://docker-mailserver.github.io/docker-mailserver/latest/usage/\n\nOr use services listed on PocketBase docs (MailerSend, Brevo, SendGrid, Mailgun, AWS SES). https://pocketbase.io/docs/going-to-production/#use-smtp-mail-server\n\n## Configure OAuth2 login/registration\n\nPocketBase OAuth2 docs: https://pocketbase.io/docs/authentication/#authenticate-with-oauth2\n\n(The warning icon on the users collection is normal when no providers are configured.)\n\n![](./assets/Snipaste_2025-11-17_18-11-27.png)\n\nIn the users collection → Settings → Options → OAuth2 → Add provider.\n\n![](./assets/collage(6).png)\n\nExample with GitHub:\n\nGo to https://github.com/settings/developers → New OAuth App\n\n![](./assets/Snipaste_2025-11-17_19-28-10.png)\n\nClick **New OAuth App** and fill out the form. In this example, `uika.top` is used for demonstration.  \n\n![](./assets/Snipaste_2025-11-17_19-31-36.png)\n\nThe **Authorization callback URL** is very important. It should be set to your own domain followed by `/api/oauth2-redirect`. See [PocketBase OAuth2](https://pocketbase.io/docs/authentication/#authenticate-with-oauth2) for details.  \n\n```\nhttps://yourdomain.com/api/oauth2-redirect\n```  \n\nAfter creation you get Client ID and Client Secret.\n\n![](./assets/Snipaste_2025-11-17_19-38-39.png)\n\nYou can also set an app logo, e.g. https://github.com/PocketTogether/pocket-chat/blob/master/resources/icon1.png\n\n## Configuring Browser Caching in the Reverse Proxy\n\n- It is not recommended to use 1Panel’s visual form to configure the reverse proxy.  \n- Instead, it is recommended to directly edit the Nginx configuration file within 1Panel and manually configure the reverse proxy and browser caching policies.  \n- This approach provides more flexibility and is better suited for the fine-grained caching control required by PocketChat (such as static asset caching, PocketBase file caching, dynamic content no-cache, etc.).\n- Starting from v0.5.0, to ensure more reliable PWA installation, you should also configure the correct MIME type for `manifest.webmanifest` in this section.\n\n```nginx\n# PocketBase file caching\nlocation ^~ /api/files/ {\n    proxy_pass http://127.0.0.1:58090;\n\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header REMOTE-HOST $remote_addr;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection $http_connection;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_http_version 1.1;\n    add_header X-Cache $upstream_cache_status;\n    proxy_ssl_server_name off;\n    proxy_ssl_name $proxy_host;\n    \n    expires 180d;\n    add_header Cache-Control \"public, max-age=15552000, s-maxage=15552000, immutable\";\n}\n\n# Static asset caching\nlocation ~ (^/assets/|^/workbox-|^/remixicon|^/Snipaste_|^/_/) {\n    proxy_pass http://127.0.0.1:58090;\n\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header REMOTE-HOST $remote_addr;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection $http_connection;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_http_version 1.1;\n    add_header X-Cache $upstream_cache_status;\n    proxy_ssl_server_name off;\n    proxy_ssl_name $proxy_host;\n    \n    expires 180d;\n    add_header Cache-Control \"public, max-age=15552000, s-maxage=15552000, immutable\";\n}\n\n# Dynamic content (HTML, API, etc.)\nlocation / {\n    proxy_pass http://127.0.0.1:58090;\n\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header REMOTE-HOST $remote_addr;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection $http_connection;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_http_version 1.1;\n    add_header X-Cache $upstream_cache_status;\n    proxy_ssl_server_name off;\n    proxy_ssl_name $proxy_host;\n\n    add_header Cache-Control \"no-cache\";\n}\n\n# Set the correct MIME type for manifest.webmanifest\nlocation = /manifest.webmanifest {\n    proxy_pass http://127.0.0.1:58090;\n\n    proxy_set_header Host $host;\n    proxy_set_header X-Real-IP $remote_addr;\n    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;\n    proxy_set_header REMOTE-HOST $remote_addr;\n    proxy_set_header Upgrade $http_upgrade;\n    proxy_set_header Connection $http_connection;\n    proxy_set_header X-Forwarded-Proto $scheme;\n    proxy_http_version 1.1;\n    add_header X-Cache $upstream_cache_status;\n    proxy_ssl_server_name off;\n    proxy_ssl_name $proxy_host;\n\n    proxy_hide_header Content-Type;\n    add_header Content-Type \"application/manifest+json\";\n    add_header Cache-Control \"no-cache\";\n}\n```\n\n### Notes on PocketBase File\n\nAll files in PocketBase (images, videos, etc.) are accessed through a fixed path:\n\n```\n/api/files/:collectionId/:recordId/:filename\n\nhttp://127.0.0.1:58090/api/files/pbc_3607937828/426c1mnva7cd4k4/image_twlm01yw5w.webp\n```\n\nEach uploaded file is stored using the original filename (sanitized) with an additional suffix — a random segment (typically 10 characters). For example:\n\n```\nimage_twlm01yw5w.webp\n```\n\nhttps://pocketbase.io/docs/files-handling/#file-url\n\n## Development Guide\n\n### PocketChat Project Directory Structure\n\n- `pocketbase/` — Folder containing PocketBase  \n- `vue3/` — Vue3 frontend folder  \n- `project-tools-node/` — Project packaging tool scripts folder  \n- `pocketbase-typegen/` is the PocketBase type-generation tool.\n- `resources/` — Image resources used in the project  \n- `note/` — Development notes (few in this project, more in [PocketTogether](#about-pockettogether))  \n- `assets/` — Images used in README.md  \n\n### PocketBase Backend\n\nIt is recommended to open the `pocketbase/` directory in VS Code for development (instead of opening the project root). For example, when editing JS files in `pocketbase/pb_hooks/`, use `pocketbase/jsconfig.json` to enforce stricter typing. JS code in `pocketbase/pb_hooks/` should use JSDoc for type definitions.\n\nTo avoid increasing repository size, `pocketbase.exe` is ignored in Git. This means the executable is not included in the repository. Before development, manually download `pocketbase.exe` from:  \nhttps://github.com/pocketbase/pocketbase/releases  \n\nUnzip and copy `pocketbase.exe` into the `pocketbase/` directory.\n\nThe specific version of `pocketbase.exe` used in this project can be found in `pocketbase/CHANGELOG.md` (use the latest entry at the top).\n\nDouble-click `pocketbase/start.sh` to start PocketBase for this project.\n\nIf you modify the database schema via the PocketBase Web UI, export it from:  \n`http://127.0.0.1:58090/_/#/settings/export-collections`  \n\nCopy the exported content into `pocketbase/pb_schema.json`, then regenerate the [TypeScript types for the backend database](#generate-backend-database-ts-types) in the frontend.\n\nNote: PocketBase does not depend on `pb_schema.json` to run. Its purpose is to track schema changes via Git and to help the frontend [generate backend database TS types](#generate-backend-database-ts-types).\n\n### Vue3 Frontend\n\nIt is recommended to open the `vue3/` directory in VS Code for development (instead of the project root).\n\n```sh\n# Project Setup\npnpm install\n\n# Compile and Hot-Reload for Development\npnpm dev\n\n# Type-Check, Compile and Minify for Production\npnpm build\n\n# Lint with ESLint\npnpm lint\n```\n\n#### Generate Backend Database TS Types\n\nThis project uses [pocketbase-typegen](https://www.npmjs.com/package/pocketbase-typegen) to generate PocketBase backend data types for the frontend:\n`\"pocketbase-typegen\": \"^1.3.1\",`\n\n【260111】I modified **pocketbase-typegen** and localized it into the `pocketbase-typegen/` directory.  \nYou should install its dependencies inside that directory before using it from the frontend:\n```sh\n# pwd\n# /e/Project/pocket-chat/pocketbase-typegen\npnpm i\n```\n\nUsing it from the frontend:\n```sh\n# pwd\n# /e/Project/pocket-chat/vue3\n\npnpm pb-typegen-json\n\n# package.json - scripts\n# \"pb-typegen-json\": \"node scripts/pocketbase-typegen.cjs\"\n```\n\nFor more details about `pocketbase-typegen/`, refer to:\n```\nvue3/scripts/pocketbase-typegen.cjs\npocketbase-typegen/README.md\npocketbase-typegen/README-pocketbase-typegen.md\n```\n\n### About PocketTogether\n\n[PocketTogether](https://github.com/PocketTogether/pocket-together) is a real-time group chat and synchronized watching platform built on PocketBase and Vue3 (currently in development). PocketChat is essentially a partial product of PocketTogether.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpockettogether%2Fpocket-chat","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpockettogether%2Fpocket-chat","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpockettogether%2Fpocket-chat/lists"}