Logo
  • Zulip homepage
  • Overview
    • Zulip overview
      • Getting started
    • Zulip architectural overview
      • Key codebases
      • Usage assumptions and concepts
      • Components
        • Django and Tornado
        • nginx
        • Supervisor
        • memcached
        • Redis
        • RabbitMQ
        • PostgreSQL
        • Nagios
      • Glossary
    • Directory structure
      • Core Python files
      • HTML templates
      • JavaScript, TypeScript, and other frontend assets
      • Tests
      • Management commands
      • Scripts
      • API and bots
      • Production Puppet configuration
      • Additional Django apps
      • Jinja2 compatibility files
      • Translation files
      • Documentation
    • Release lifecycle
      • Server and web app versions
        • Stable releases
        • Git versions
        • What version am I running?
        • Versioned documentation
      • Client apps
        • Mobile app
        • Desktop app
        • Terminal app
      • Server and client app compatibility
        • Upgrade nag
      • Operating system support
      • API bindings
    • Roadmap
      • Server and web app roadmap
      • Mobile app roadmap
    • Version history
      • Zulip Server 10.x series
        • Zulip Server 10.3
        • Zulip Server 10.2
        • Zulip Server 10.1
        • Zulip Server 10.0
      • Zulip Server 9.x series
        • Zulip Server 9.4
        • Zulip Server 9.3
        • Zulip Server 9.2
        • Zulip Server 9.1
        • Zulip Server 9.0
      • Zulip Server 8.x series
        • Zulip Server 8.5
        • Zulip Server 8.4
        • Zulip Server 8.3
        • Zulip Server 8.2
        • Zulip Server 8.1
        • Zulip Server 8.0
      • Zulip Server 7.x series
        • Zulip Server 7.5
        • Zulip Server 7.4
        • Zulip Server 7.3
        • Zulip Server 7.2
        • Zulip Server 7.1
        • Zulip Server 7.0
      • Zulip Server 6.x series
        • Zulip Server 6.2
        • Zulip Server 6.1
        • Zulip Server 6.0
      • Zulip Server 5.x series
        • Zulip Server 5.7
        • Zulip Server 5.6
        • Zulip Server 5.5
        • Zulip Server 5.4
        • Zulip Server 5.3
        • Zulip Server 5.2
        • Zulip Server 5.1
        • Zulip Server 5.0
      • Zulip Server 4.x series
        • Zulip Server 4.11
        • Zulip Server 4.10
        • Zulip Server 4.9
        • Zulip Server 4.8
        • Zulip Server 4.7
        • Zulip Server 4.6
        • Zulip Server 4.5
        • Zulip Server 4.4
        • Zulip Server 4.3
        • Zulip Server 4.2
        • Zulip Server 4.1
        • Zulip Server 4.0
      • Zulip Server 3.x series
        • Zulip Server 3.4
        • Zulip Server 3.3
        • Zulip Server 3.2
        • Zulip Server 3.1
        • Zulip Server 3.0
      • Zulip Server 2.1.x series
        • Zulip Server 2.1.8
        • Zulip Server 2.1.7
        • Zulip Server 2.1.6
        • Zulip Server 2.1.5
        • Zulip Server 2.1.4
        • Zulip Server 2.1.3
        • Zulip Server 2.1.2
        • Zulip Server 2.1.1
        • Zulip Server 2.1.0
      • Zulip Server 2.0.x series
        • Zulip Server 2.0.8
        • Zulip Server 2.0.7
        • Zulip Server 2.0.6
        • Zulip Server 2.0.5
        • Zulip Server 2.0.4
        • Zulip Server 2.0.3
        • Zulip Server 2.0.2
        • Zulip Server 2.0.1
        • Zulip Server 2.0.0
      • Zulip Server 1.9.x series
        • Zulip Server 1.9.2
        • Zulip Server 1.9.1
        • Zulip Server 1.9.0
      • Zulip Server 1.8.x series
        • Zulip Server 1.8.1
        • Zulip Server 1.8.0
      • Zulip Server 1.7.x series
        • Zulip Server 1.7.2
        • Zulip Server 1.7.1
        • Zulip Server 1.7.0
      • Zulip Server 1.6.x and older
        • Zulip Server 1.6.0
        • Zulip Server 1.5.2
        • Zulip Server 1.5.1
        • Zulip Server 1.5.0
        • Zulip Server 1.4.3
        • Zulip Server 1.4.2
        • Zulip Server 1.4.1
        • Zulip Server 1.4.0
        • Zulip Server 1.3.13
        • Zulip Server 1.3.12
        • Zulip Server 1.3.11
        • Zulip Server 1.3.10
        • Zulip Server 1.3.9
        • Zulip Server 1.3.8
        • Zulip Server 1.3.7
      • Upgrade notes
  • Zulip in production
    • Requirements and scalability
      • Server
        • General
        • Operating system
        • Hardware specifications
        • Network and security specifications
      • Credentials needed
        • SSL certificate
        • Outgoing email
      • Scalability
    • Install a Zulip server
      • Installation process overview
      • Step 0: Set up a base server
      • Step 1: Download the latest release
      • Step 2: Install Zulip
        • Installer options
      • Step 3: Create a Zulip organization, and log in
      • Getting started with Zulip
    • Troubleshooting and monitoring
      • Overview and resources
      • Using supervisorctl
        • Checking status with supervisorctl status
        • Restarting services with supervisorctl restart
        • Stopping services with supervisorctl stop
      • Troubleshooting services
        • Restrict unattended upgrades
      • Monitoring
        • Nagios configuration
      • Memory leak mitigation
      • Troubleshooting the Zulip installer
        • The zulip user’s password.
    • Management commands
      • Running management commands
        • Accessing an organization’s string_id
      • manage.py shell
      • Other useful manage.py commands
      • Custom management commands
    • Server configuration
      • Server settings overview
      • Changing server settings
      • Customizing user onboarding
        • Navigation tour video
        • Terms of Service and Privacy policy
    • System configuration
      • Truthy values
      • [machine]
        • puppet_classes
        • pgroonga
        • timesync
      • [deployment]
        • deploy_options
        • git_repo_url
      • [application_server]
        • http_only
        • nginx_listen_port
        • nginx_worker_connections
        • queue_workers_multiprocess
        • rolling_restart
        • service_file_descriptor_limit
        • s3_memory_cache_size
        • s3_disk_cache_size
        • s3_cache_inactive_time
        • thumbnail_workers
        • email_senders_workers
        • nameserver
        • uwsgi_listen_backlog_limit
        • uwsgi_processes
        • access_log_retention_days
        • katex_server
        • katex_server_port
      • [postfix]
        • mailname
      • [postgresql]
        • effective_io_concurrency
        • listen_addresses
        • random_page_cost
        • replication_primary
        • replication_user
        • skip_backups
        • backups_disk_concurrency
        • backups_directory
        • backups_incremental
        • backups_storage_class
        • backups_compression_method
        • missing_dictionaries
        • ssl_ca_file
        • ssl_cert_file
        • ssl_key_file
        • ssl_mode
        • version
      • [memcached]
        • memory
        • max_item_size
        • size_reporting
      • [loadbalancer]
        • ips
        • rejects_http_requests
      • [http_proxy]
        • host
        • port
        • listen_address
        • enable_for_camo
      • [sentry]
        • organization
        • project
    • Mobile push notification service
      • Signing up
      • Plan management
        • Plan management for a Zulip organization
        • Plan management for an entire Zulip server
      • Why a push notification service is necessary
      • Security and privacy
        • Uploading basic metadata
        • Uploading usage statistics
      • Rate limits
      • Updating your server’s registration
      • Moving your registration to a new server
        • Transferring your registration if you lost the original credentials
      • Deactivating your server’s registration
        • Pausing use of the Mobile Push Notification Service
      • Sending push notifications directly from your server
    • Upgrade Zulip
      • Upgrading to a release
        • What to expect during an upgrade
      • Upgrading from a Git repository
        • Upgrading to an unreleased version of Zulip
      • Updating settings.py inline documentation
      • Troubleshooting and rollback
        • Rolling back to a prior version
      • Deployment hooks
      • Preserving local changes to service configuration files
        • nginx configuration changes
      • Upgrading PostgreSQL
      • Upgrading the operating system
        • Upgrading from Ubuntu 22.04 Jammy to 24.04 Noble
        • Upgrading from Ubuntu 20.04 Focal to 22.04 Jammy
        • Upgrading from Ubuntu 18.04 Bionic to 20.04 Focal
        • Upgrading from Ubuntu 16.04 Xenial to 18.04 Bionic
        • Upgrading from Debian 11 to 12
        • Upgrading from Debian 10 to 11
        • Upgrading from Debian 9 to 10
    • Modify Zulip
      • Making changes
        • Upgrading to future releases
        • Making changes with docker-zulip
      • Applying changes from main
        • Applying a small change
        • Upgrading to main
      • Contributing patches
    • Security model
      • Secure your Zulip server like your email server
      • Encryption and authentication
        • Passwords
      • Messages and history
      • Users and bots
      • User-uploaded content and user-generated requests
      • Rate limiting
      • Final notes and security response
    • Authentication methods
      • Email and password
      • Plug-and-play SSO (Google, GitHub, GitLab)
      • LDAP (including Active Directory)
        • Synchronizing data
        • Multiple LDAP searches
        • Restricting access to an LDAP group
        • Restricting LDAP user access to specific organizations
        • Troubleshooting
      • SAML
        • IdP-initiated SSO
        • Restricting access to specific organizations
        • Synchronizing user role or custom profile fields during login
        • SCIM
        • Using Keycloak as a SAML IdP
        • Using Authentik as a SAML IdP
        • SAML Single Logout
      • Apache-based SSO with REMOTE_USER
        • Setup instructions for Apache-based SSO
        • Troubleshooting Apache-based SSO
        • Life of an Apache-based SSO login attempt
      • Sign in with Apple
      • OpenID Connect
      • JWT
      • Configuring a custom Python wrapper around the authenticate mechanism
      • Adding more authentication backends
      • Development only
    • Backups, export and import
      • Backups
        • Restoring backups
        • What is included
        • Restore from manual backups
      • Data export
        • Consider upgrading
        • Preventing changes during the export
        • Export your Zulip data
      • Import into a new Zulip server
        • Import options
        • Logging in
        • Deleting and re-importing
      • Compliance exports
      • Database-only backup tools
        • Streaming backups to S3
        • Streaming backups to local disk
    • PostgreSQL database details
      • Separate PostgreSQL database
        • Cloud-provider-managed PostgreSQL (e.g., Amazon RDS)
        • Remote PostgreSQL database
      • PostgreSQL warm standby
      • PostgreSQL vacuuming alerts
    • File upload backends
      • S3 backend configuration
        • Google Cloud Platform
      • S3 local caching
      • nginx DNS nameserver configuration
      • S3 bucket policy
      • Migrating from local uploads to Amazon S3 backend
      • S3 data storage class
      • Data export bucket
    • Installing SSL certificates
      • Manual install
        • Testing
      • Certbot (recommended)
        • At initial Zulip install
        • After Zulip is already installed
        • How it works
        • Renewal
      • Self-signed certificate
      • Troubleshooting
        • The Android app can’t connect to the server
        • The iOS app can’t connect to the server
        • The Android app connects to the server on some devices but not others
    • Outgoing email
      • How to configure
      • Email services
        • Free outgoing email services
        • Using system email
        • Using Gmail for outgoing email
        • Logging outgoing email to a file for prototyping
      • Troubleshooting
        • Advanced troubleshooting
    • Deployment options
      • Installing Zulip from Git
      • Zulip in Docker
      • Zulip installer details
        • Advanced installer options
      • Installing on an existing server
      • Deployment hooks
        • Zulip message deploy hook
        • Sentry deploy hook
      • Running Zulip’s service dependencies on different machines
      • Using an alternate port
      • Customizing the outgoing HTTP proxy
        • S3 file storage requests and outgoing proxies
    • Reverse proxies
      • Installer options
        • Configuring Zulip to allow HTTP
        • Configuring Zulip to trust proxies
      • nginx configuration
      • Apache2 configuration
      • HAProxy configuration
      • Other proxies
    • Hosting multiple organizations
      • Subdomains
        • SSL certificates
        • Other hostnames
        • The root domain
        • Changing subdomains
        • Authentication
        • The system bot realm
        • Migrating / troubleshooting
      • Open realm creation
    • Incoming email integration
      • Local delivery setup
      • Polling setup
    • Video call providers
      • Jitsi
      • Zoom
        • Server to Server OAuth app
        • General OAuth app
        • Configure your Zulip server
      • BigBlueButton
    • AI integrations
      • Built-in AI features
        • Data privacy
        • General configurations
        • Topic summarization beta
    • GIPHY GIF integration
      • Apply for API key
    • SCIM provisioning
      • Server configuration
      • Additional options
  • Contributing to Zulip
    • Contributing guide
      • Learning from the docs
      • Getting started
        • Learning how to use Git (the Zulip way)
        • Setting up your development environment and diving in
      • Finding an issue to work on
        • Where to look for an issue
        • Picking an issue to work on
        • Claiming an issue
      • Getting help
      • What makes a great Zulip contributor?
      • Submitting a pull request
      • Beyond the first issue
      • Common questions
      • Outreach programs
    • Zulip Code of Conduct
      • Expected behavior
      • Unacceptable behavior
      • Reporting and enforcement
      • Scope
      • License and attribution
      • Moderating the Zulip community
    • How we communicate
      • Providing suggestions and feedback
      • Handling disagreements
      • Expressing your appreciation
    • Asking great questions
      • Where to ask your question
      • How to ask a great question
      • Follow the community guidelines
    • Design discussions
      • Guidelines for all participants
      • Participant roles
      • Guidelines for code contributors
        • When to post
        • Guidelines for requesting design feedback
      • Guidelines for community moderators
        • Improving the quality of discussions
        • Moving threads to the most appropriate channel
      • Guidelines for decision makers
        • Managing the discussion
        • From discussion to decision
    • Commit discipline
      • Each commit must be coherent
      • Commits should generally be minimal
        • When not to be overly minimal
      • Write a clean commit history
      • Commit messages
        • Commit summary, part 1
        • Commit summary, part 2
        • Examples of good commit summaries
        • Commit description
        • Examples of good commit messages
    • Code style and conventions
      • Be consistent with existing code
        • Use the linters
        • Use tests to verify your logic
      • Follow Zulip conventions and practices
        • Observe a reasonable line length
        • Tag user-facing strings for translation
        • Correctly prepare paths destined for state or log files
        • Never include secrets inline with code
        • Familiarize yourself with rules about third-party code
      • Python-specific conventions and practices
      • JavaScript and TypeScript conventions and practices
        • Build DOM elements in Handlebars
        • Attach behaviors to event listeners
        • Declare variables using const and let
        • Manipulate objects and arrays with modern methods
      • HTML and CSS
      • Dangerous constructs in Django
        • Avoid excessive database queries
        • Never do direct database queries (UserProfile.objects.get(), Client.objects.get(), etc.)
        • Don’t use Django model objects as keys in sets/dicts
        • Don’t call user_profile.save() without update_fields
        • Don’t update important model objects with raw saves
        • Don’t use naive datetime objects
      • Dangerous constructs in JavaScript and TypeScript
        • Do not use for...in statements to traverse arrays
    • Reviewing Zulip code
      • Principles of code review
        • Reviewing your own code
        • Reviewing other contributors’ code
      • How to review code
        • Code review checklist
        • Automated testing
        • Manual testing
      • Review process and communication
        • Asking for a code review
        • Reviewing someone else’s code
        • Responding to review feedback
      • Additional resources
    • Submitting a pull request
      • Write clear code
      • Organize your proposed changes
      • Explain your changes
        • Discussions in the development community
      • Review your own work
      • Submit your pull request for review
      • Draft pull requests
      • Demonstrating visual changes
    • Pull request review process
      • Labels for managing the stages of pull request review
      • Stages of a pull request review
      • How to help move the review process forward
      • Follow-ups
    • Continuing unfinished work
      • Find work to be completed
      • Review existing work and feedback
      • Decide how to use prior work
      • Credit prior work in your commit history
      • Present your pull request
    • Using zulipbot
      • Usage
        • Contributing
    • Reporting bugs
      • What to include in a bug report
      • Filing a GitHub issue
      • Starting a conversation about a possible bug
      • Managing bug reports
    • Suggesting features and improvements
      • What to include in your proposal
      • Starting a conversation about a suggested feature or improvement
      • Filing a GitHub issue
      • Evaluation and onboarding feedback
    • Counting contributions
      • How the contribution stats are calculated
      • Old email addresses
      • Relevant source code
      • Attribution for non-code contributions
    • Licensing
      • Contributing your own work
      • Contributing someone else’s work
  • Development environment
    • Development environment installation
      • Requirements
      • Recommended setup
      • Vagrant setup
      • Advanced setup
      • Slow internet connections
      • Installing remotely
      • Next steps
    • Recommended setup
      • Requirements
      • Step 0: Set up Git & GitHub
      • Step 1: Install prerequisites
      • Step 2: Get Zulip code
      • Step 3: Start the development environment
      • Step 4: Developing
        • Where to edit files
        • VSCode setup (optional)
        • Understanding run-dev debugging output
        • Committing and pushing changes with Git
        • Maintaining the development environment
        • Rebuilding the development environment
        • Shutting down the development environment for use later
        • Resuming the development environment
      • Next steps
      • Troubleshooting and common errors
        • Vagrant guest doesn’t show (zulip-server) at start of prompt
        • Vagrant was unable to mount VirtualBox shared folders
        • ssl read error
        • Unmet dependencies error
        • ssh connection closed by remote host
        • os.symlink error
        • Hyper-V error messages
        • Connection timeout on vagrant up
        • Vagrant was unable to communicate with the guest machine
        • Vagrant up fails with subprocess.CalledProcessError
        • VBoxManage errors related to VT-x or WHvSetupPartition
        • OSError: [Errno 26] Text file busy
      • Specifying an Ubuntu mirror
      • Specifying a proxy
      • Using a different port for Vagrant
      • Customizing CPU and RAM allocation
    • Advanced setup
      • Installing directly on Ubuntu, Debian, CentOS, or Fedora
      • Installing using Vagrant with VirtualBox on Windows 10
        • Running Git BASH as an administrator
      • Using the Vagrant Hyper-V provider on Windows (beta)
        • Problems you may encounter
      • Newer versions of supported platforms
    • Using the development environment
      • Common
      • Server
      • Web
      • Mobile
    • Developing remotely
      • Connecting to the remote environment
      • Setting up user accounts
      • Setting up the development environment
      • Running the development server
      • Making changes to code on your remote development server
        • Editing locally
        • Editing remotely
        • Next steps
      • Using an nginx reverse proxy
    • Authentication in the development environment
      • Email and password
      • Google
      • GitHub
      • GitLab
      • Apple
      • SAML
      • When SSL is required
      • Testing LDAP in development
        • Testing avatar and custom profile field synchronization
        • Automated testing
      • Two factor authentication
      • Password form implementation
    • Testing the installer
      • Configuring
      • Running a test install
        • Build and unpack a release tarball
        • Test an install
        • See running containers after installation
        • Connect to a running container
        • Stopping and destroying containers
        • Iterating on the installer
  • Developer tutorials
    • Writing a new application feature
      • General process
        • Files impacted
        • Adding a field to the database
        • Backend changes
        • Frontend changes
        • Documentation changes
      • Example feature
        • Update the model
        • Create the migration
        • Test your migration changes
        • Handle database interactions
        • Update application state
        • Add a new view
        • Backend tests
        • Update the frontend
        • Frontend tests
        • Update documentation
    • Writing views in Zulip
      • What this covers
      • What is a view?
      • Modifying urls.py
      • Writing human-readable views
        • Decorators used for webpage views
        • Writing a template
      • Writing API REST endpoints
        • Request variables
        • Deciding which HTTP verb to use
        • Idempotency
        • Making changes to the database
        • Calling from the web application
        • Calling from an API client
      • Legacy endpoints used by the web client
      • Incoming webhook integrations
    • Life of a request
      • A request is sent to the server, and handled by nginx
      • Static files are served directly by nginx
      • nginx routes other requests between Django and Tornado
      • Django routes the request to a view in urls.py files
      • Views serving HTML are internationalized by server path
      • API endpoints use REST
        • PUT is only for creating new things
        • OPTIONS
        • Incoming webhook integrations may not be RESTful
      • Django calls rest_dispatch for REST endpoints, and authenticates
      • The view will authorize the user, extract request variables, and validate them
      • Results are given as JSON
    • Reading list
      • General programming/IT
      • Python
      • Java/Android
      • JavaScript/ECMAScript
      • TypeScript
      • Git/version control systems (VCS)
      • Computer science/algorithms
      • Community experience
      • Competitions/camps
      • Massive open online courses (MOOC) platforms
    • Screenshot and GIF software
      • Screenshot tools by platform
        • Browser
        • macOS
        • Windows
        • Linux
      • GIF tools by platform
        • Browser
        • macOS
        • Windows
        • Linux
    • Shell tips
      • The prompt ($)
      • Tilde character (~)
      • Change directory (cd)
      • Running commands as root (sudo)
      • Escaping characters
      • Sequencing commands
      • Splitting commands into multiple lines
      • Arguments
      • Shebang
      • Understanding commands
      • Cheatsheet
      • Git
  • Git guide
    • Quick start
    • Set up Git
      • Install and configure Git, join GitHub
      • Get a graphical client
    • Zulip-specific tools
      • Set up Git repo script
      • Configure continuous integration for your Zulip fork
      • Reset to pull request
      • Fetch a pull request and rebase
      • Fetch a pull request without rebasing
      • Push to a pull request
      • Delete unimportant branches
      • Merge conflict on pnpm-lock.yaml file
    • How Git is different
    • Important Git terms
      • branch
      • cache
      • checkout
      • commit
      • fast-forward
      • fetch
      • hash
      • head
      • HEAD
      • index
      • pull
      • push
      • rebase
    • Get Zulip code
      • Step 1a: Create your fork
      • Step 1b: Clone to your machine
      • Step 1c: Connect your fork to Zulip upstream
      • Step 2: Set up the Zulip development environment
      • Step 3: Configure continuous integration for your fork
    • Working copies
      • Workflows
      • Relevant Git commands
    • Using Git as you work
      • Know what branch you’re working on
      • Keep your fork up to date
      • Work on a feature branch
      • Run linters and tests locally
      • Stage changes
        • Get status of working directory
        • Stage additions with git add
        • Stage deletions with git rm
      • Commit changes
      • Push your commits to GitHub
      • Examine and tidy your commit history
      • Force-push changes to GitHub after you’ve altered your history
    • Pull requests
      • Draft pull requests
      • Create a pull request
        • Step 0: Make sure you’re on a feature branch (not main)
        • Step 1: Update your branch with git rebase
        • Step 2: Push your updated branch to your remote fork
        • Step 3: Open the pull request
      • Update a pull request
    • Collaborate
      • Fetch another contributor’s branch
      • Check out a pull request locally
    • Fixing commits
      • Fixing the last commit
        • Changing the last commit message
        • Changing the last commit
      • Fixing older commits
        • Changing commit messages
        • Deleting old commits
      • Squashing commits
      • Reordering commits
      • Pushing commits after tidying them
    • Reviewing changes
      • Changes on (local) working tree
      • Changes within branches
      • Changes between branches
    • Get and stay out of trouble
      • Undo a merge commit
      • Restore a lost commit
      • Recover from a git rebase failure
      • Working from multiple computers
    • Git cheat sheet
      • Common commands
      • Detailed cheat sheet
  • Code testing
    • Testing overview
      • Running tests
      • Major test suites
      • Other test suites
      • Internet access inside test suites
        • Documentation tests
    • Linters
      • Overview
      • Running the linters
      • General considerations
      • Lint checks
      • lint
        • Special options
        • Lint checks
      • Philosophy
        • Speed
        • Accuracy
        • Completeness
    • Backend Django tests
      • Overview
      • Running tests
      • Writing tests
        • Setting up data for tests
        • Testing code that accesses the filesystem
        • Testing with mocks
      • Zulip testing philosophy
        • Endpoint tests
        • Library tests
        • Fixture-driven tests
        • Mocks and stubs
        • Template tests
        • SQL performance tests
        • Event-based tests
        • Negative tests
      • Testing considerations
    • JavaScript/TypeScript unit tests
      • How the node tests work
      • Handling dependencies in unit tests
      • Creating new test modules
      • Verifying HTML templates with mock_template
      • Coverage reports
      • Editor debugger integration
      • Webstorm integration setup
      • Running tests with the debugger
    • Web frontend black-box Puppeteer tests
      • Running tests
      • How Puppeteer tests work
      • Debugging Puppeteer tests
      • Writing Puppeteer tests
    • Python static type checker (mypy)
      • Installing mypy
      • Running mypy on Zulip’s code locally
      • Mypy is there to find bugs in Zulip before they impact users
      • Mypy stubs for third-party modules
      • Working with types from django-stubs
      • Using @overload to accurately describe variations
      • Best practices
        • When is a type annotation justified?
        • Avoid the Any type
        • Avoid cast()
        • Avoid # type: ignore comments
        • Avoid other unchecked constructs
        • Use Optional and None correctly
        • Read-only types
        • Typing decorators
      • Troubleshooting advice
    • TypeScript static types
      • Type checking
      • Linting and style
      • Migration strategy
    • Continuous integration (CI)
      • Goals
      • GitHub Actions
        • Useful debugging tips and tools
        • Suites
        • Configuration
        • Images
        • Performance optimizations
    • Manual testing
      • Basic stuff
        • Message view
        • Messagebox
        • Message editing
        • Narrowing
        • Composing messages
        • Popover menus
        • Sidebar filtering
        • Channel permissions
        • Search
        • Channel settings
        • User settings
        • Keyboard shortcuts
        • Miscellaneous menu options
        • Inviting users/tutorial
        • To be continued…
    • Testing philosophy
      • Effective testing allows us to move quickly
      • Test suite performance and reliability are critical
      • Integration testing or unit testing?
      • Avoid duplicating code with security impact
      • Share test setup code
      • What isn’t tested probably doesn’t work
  • Subsystems documentation
    • Provisioning and third-party dependencies
      • Provisioning
        • PROVISION_VERSION
      • Philosophy on adding third-party dependencies
      • System packages
      • Python packages
      • JavaScript and other frontend packages
      • Node.js and pnpm
      • ShellCheck and shfmt
      • Puppet packages
      • Other third-party and generated files
        • Emoji
        • Translations data
        • Pygments data
      • Modifying provisioning
    • Settings system
      • Server settings
        • Testing non-default settings
      • Realm settings
    • HTML and CSS
      • Zulip CSS organization
      • Editing Zulip CSS
      • CSS style guidelines
        • Avoid duplicated code
        • Be consistent with existing similar UI
        • Use clear, unique names for classes and object IDs
      • Validating CSS
      • HTML templates
        • Behavior
        • Backend templates
        • Frontend templates
        • Toolchain
        • Translation
        • Tooltips
      • Static asset pipeline
        • Primary build process
        • Adding static files
        • How it works in production
        • ES6/TypeScript modules
    • Icons
      • Using icons
      • Adding a new icon
      • Changing an icon
    • Accessibility
      • Guidelines
      • Tools
      • GitHub issues
      • Additional resources
    • Real-time push and events
      • Generation system
      • Delivery system
      • The initial data fetch
        • Testing
        • Messages
      • Schema changes
    • Sending messages
      • Message lists
      • Compose area
      • Backend implementation
      • Local echo
        • Local echo in message editing
      • Putting it all together
      • Message editing
        • Inline URL previews
      • Soft deactivation
    • Notifications in Zulip
      • Important corner cases
      • The mobile/email notifications flow
    • Queue processors
      • Adding a new queue processor
      • Publishing events into a queue
      • Clearing a RabbitMQ queue
    • Unread counts and the pointer
      • Pointer logic
        • Recipient bar: message you clicked
        • Search, sidebar click, or new tab: unread/recent matching narrow
        • Unnarrow: previous sequence
        • Forced reload: state preservation
      • Unread count logic
      • Testing and development
    • Markdown implementation
      • Testing
      • Changing Zulip’s Markdown processor
      • Per-realm features
      • Zulip’s Markdown philosophy
      • Zulip’s changes to Markdown
        • Basic syntax
        • Lists
        • Links
        • Code
        • Other
    • Caching in Zulip
      • Backend caching with memcached
        • The core implementation
        • Cautions
        • Cache invalidation after writes
        • Production deployments and database migrations
        • Automated testing and memcached
        • Manual testing and memcached
        • Performance
      • In-process caching in Django
      • Browser caching of state
    • Performance and scalability
      • Load profiles
      • Major Zulip endpoints
        • Tornado
        • Presence
        • Fetching page_params
        • Fetching message history
        • User uploads
        • Sending and editing messages
        • Other endpoints
      • Queue processors and cron jobs
      • Service scalability
    • Realms in Zulip
      • Creating realms
        • Using unique link generator
      • Subdomains
        • Working with subdomains in development environment
    • Management commands
      • Writing management commands
    • Schema migrations
      • Automated testing for migrations
      • Schema and initial data changes
    • URL hashes and deep linking
      • Hashchange
      • Server-initiated reloads
      • All reloads
    • Emoji
      • Emoji codes
        • Custom emoji
      • Tooling
      • Picking emoji names
    • Onboarding Steps
      • Configuring a New Onboarding Step
        • Step 1: Add the Onboarding Step Name
        • Step 2: Display the Onboarding Step
        • Step 3: Mark the Onboarding Step as Read
    • Full-text search
      • The default full-text search implementation
      • Multi-language full-text search
        • Enabling PGroonga
        • Disabling PGroonga
    • Email
      • Development and testing
        • Testing in a real email client
        • Notes
      • Email templates
    • Analytics
      • Analytics backend overview
      • The *Count database tables
      • CountStats
      • The FillState table
      • Performance strategy
      • Backend testing
      • LoggingCountStats
      • Analytics UI development and testing
        • Setup and testing
        • Adding or editing /stats graphs
        • /activity page
    • Clients in Zulip
      • Analytics
      • Integrations
    • Logging and error reporting
      • Backend error reporting
        • Sentry error logging
        • Backend logging
      • Blueslip frontend error reporting
        • Sentry JavaScript error logging
      • Frontend performance reporting
    • Typing indicators
      • Privacy settings
      • Writing user
      • Server
      • Receiving user
      • Ecosystem
      • Roadmap
    • Upgrading Django
    • Zulip server release checklist
      • A week before the release
      • Final release preparation
      • Executing the release
      • Post-release
    • Zulip PyPI packages release checklist
      • Other PyPI packages maintained by Zulip
    • UI: input pills
      • Setup
      • Basic usage
      • Typeahead
        • onPillCreate and onPillRemove methods
    • Presence
    • Unread message synchronization
    • Billing (Development)
      • Common setup
      • Manual testing
        • Setup
        • Test card numbers
        • Flows to test
      • Upgrading Stripe API versions
      • Writing tests
    • Widgets
      • What is a widget?
      • /me messages
      • Polls, todo lists, and games
        • Data flow
        • Backward compatibility
        • Adding widgets
      • zform (trivia quiz bot)
      • Data flow
    • Slash commands
      • Data flow
      • Typeahead
    • Thumbnailing
      • libvips
      • Avatars
      • Emoji
      • Realm logos
      • Realm icons
      • File uploads
        • Images
        • Migrations
        • Videos and PDFs
  • Writing documentation
    • Documentation systems
      • Developer and sysadmin documentation
      • Core website documentation
      • User-facing documentation
        • Help center documentation
        • Integrations documentation
        • API documentation
      • Automated testing
    • Writing help center articles
      • Guide to writing help center articles
        • Getting started
        • Updating an existing article
        • Adding a new article
        • Redirecting an existing article
      • Writing style
        • User interface
        • Voice
        • Keyboard shortcuts
      • Markdown features
        • Images
        • Icons
        • Macros
        • Tips and warnings
        • Tab switcher
    • Documenting an integration
      • Markdown macros
      • Writing guidelines
        • General writing guidelines
        • Guidelines for specific steps
        • Screenshots
    • Documenting REST API endpoints
      • How it works
        • Title and description
        • Usage examples
        • Parameters
        • Response with examples
      • Step by step guide
      • Why a custom system?
      • Debugging schema validation errors
        • Deconstructing the error output
        • Adding a realm setting
    • OpenAPI configuration
      • Working with the zulip.yaml file
        • Configuration
        • Endpoint definitions
        • Schemas
      • Zulip Swagger YAML style:
      • Tips for working with YAML:
        • Formatting help:
        • Examples:
  • Translating Zulip
    • Translation guidelines
      • Translators’ workflow
        • Testing translations
        • Machine translation
        • Translation style guides
        • Capitalization
    • Internationalization for developers
      • How internationalization impacts Zulip’s UI
      • What should be marked for translation
      • How to mark a string for translation
      • Translation syntax in Zulip
        • Web application translations
        • Server translations
      • Translation process
      • Translation resource files
      • Working with Transifex
        • Transifex config
        • Transifex CLI setup
      • Additional resources
    • Chinese translation style guide(中文翻译指南)
      • Note(题记)
      • Terms(术语)
      • Phrases(习惯用语)
      • Others(其它)
    • Finnish translation style guide
      • Guidelines
        • Word order
        • Grammatical case (Sijamuodot)
        • Loan word (Lainasanat)
        • Please, in error messages
        • Zulip word inflection
        • Your -expression
        • Comma
      • Terms
      • Other
    • French translation style guide
      • Community
      • Rules
      • Terms
    • German translation style guide (Richtlinien für die deutsche Übersetzung)
      • Rules
        • Formal or informal?
        • Gender-inclusive language
        • Form of address
        • Form of instruction
        • Rules for labels
        • Concatenation of words
        • Anglicisms
        • Special characters
        • False friends
        • Other
      • Terms (Begriffe)
      • Phrases (Ausdrücke)
      • Other (Verschiedenes)
    • Hindi translation style guide (हिन्दी अनुवाद शैली मार्गदर्शक)
      • Terms (शर्तें)
      • Phrases (वाक्यांश)
      • Others (अन्य)
    • Japanese translation style guide
      • Rules
      • Terms
    • Polish translation style guide
      • Special terms used in Zulip
    • Russian translation style guide
      • Перевод некоторых терминов
    • Spanish translation style guide
      • Términos
      • Frases
      • Otros
    • Urdu translation style guide(انداذِ ترجمہ کا رہنما)
      • Terms(اصطلاحات)
      • Phrases (فِقْرے)
      • Others(مختلف دیگر)
  • Outreach programs
    • Outreach programs overview
      • About Zulip
      • Outreach program experience
    • How to apply
      • Application criteria
      • Getting started
      • Putting together your application
        • What to include
        • Project proposals
        • Circulating your application for feedback
    • How to have an amazing experience
      • Your goals
      • You and your mentor
      • Communication and check-ins
        • Getting feedback and advice
        • How to post your check-ins
      • Peer reviews
      • How do I figure out what to work on?
        • Prioritization
        • What about my proposal?
        • Tips for finding issues to pick up
        • Staying productive
      • How else can I contribute?
      • Timeline extensions for GSoC
    • GSoC project ideas
      • Project size
      • Focus areas
      • Project ideas by area
        • Full stack and web frontend focused projects
        • Terminal app
        • Desktop app
        • Mobile app
    • Mentoring
      • Who can mentor
      • Supporting your mentee
        • Establishing communication patterns
      • Managing challenges
  • Index
Zulip
  • Writing documentation
  • View page source

Writing documentation

  • Documentation systems
    • Developer and sysadmin documentation
    • Core website documentation
    • User-facing documentation
      • Help center documentation
      • Integrations documentation
      • API documentation
    • Automated testing
  • Writing help center articles
    • Guide to writing help center articles
      • Getting started
      • Updating an existing article
      • Adding a new article
      • Redirecting an existing article
    • Writing style
      • User interface
      • Voice
      • Keyboard shortcuts
    • Markdown features
      • Images
      • Icons
      • Macros
      • Tips and warnings
      • Tab switcher
  • Documenting an integration
    • Markdown macros
    • Writing guidelines
      • General writing guidelines
      • Guidelines for specific steps
      • Screenshots
  • Documenting REST API endpoints
    • How it works
      • Title and description
      • Usage examples
      • Parameters
      • Response with examples
    • Step by step guide
    • Why a custom system?
    • Debugging schema validation errors
      • Deconstructing the error output
      • Adding a realm setting
  • OpenAPI configuration
    • Working with the zulip.yaml file
      • Configuration
      • Endpoint definitions
      • Schemas
    • Zulip Swagger YAML style:
    • Tips for working with YAML:
      • Formatting help:
      • Examples:
Previous Next

© Copyright 2012–2015 Dropbox, Inc., 2015–2021 Kandra Labs, Inc., and contributors.

Built with Sphinx using a theme provided by Read the Docs.