# Table of Contents
- [Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation](#nextcloud-developer-documentation-nextcloud-latest-developer-manual-latest-documentation)
- [Development process — Nextcloud latest Developer Manual latest documentation](#development-process-nextcloud-latest-developer-manual-latest-documentation)
- [Coding style & general guidelines — Nextcloud latest Developer Manual latest documentation](#coding-style-general-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Prologue — Nextcloud latest Developer Manual latest documentation](#prologue-nextcloud-latest-developer-manual-latest-documentation)
- [Interface & interaction design — Nextcloud latest Developer Manual latest documentation](#interface-interaction-design-nextcloud-latest-developer-manual-latest-documentation)
- [Code of conduct — Nextcloud latest Developer Manual latest documentation](#code-of-conduct-nextcloud-latest-developer-manual-latest-documentation)
- [Getting started — Nextcloud latest Developer Manual latest documentation](#getting-started-nextcloud-latest-developer-manual-latest-documentation)
- [ExApp development — Nextcloud latest Developer Manual latest documentation](#exapp-development-nextcloud-latest-developer-manual-latest-documentation)
- [Development overview — Nextcloud latest Developer Manual latest documentation](#development-overview-nextcloud-latest-developer-manual-latest-documentation)
- [Technical details — Nextcloud latest Developer Manual latest documentation](#technical-details-nextcloud-latest-developer-manual-latest-documentation)
- [Compatibility with the app ecosystem — Nextcloud latest Developer Manual latest documentation](#compatibility-with-the-app-ecosystem-nextcloud-latest-developer-manual-latest-documentation)
- [Help and communication — Nextcloud latest Developer Manual latest documentation](#help-and-communication-nextcloud-latest-developer-manual-latest-documentation)
- [Bugtracker — Nextcloud latest Developer Manual latest documentation](#bugtracker-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Frequently Asked Questions — Nextcloud latest Developer Manual latest documentation](#frequently-asked-questions-nextcloud-latest-developer-manual-latest-documentation)
- [Setting up dev environment — Nextcloud latest Developer Manual latest documentation](#setting-up-dev-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Security guidelines — Nextcloud latest Developer Manual latest documentation](#security-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [App publishing and maintenance — Nextcloud latest Developer Manual latest documentation](#app-publishing-and-maintenance-nextcloud-latest-developer-manual-latest-documentation)
- [Static analysis — Nextcloud latest Developer Manual latest documentation](#static-analysis-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end code — Nextcloud latest Developer Manual latest documentation](#front-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [Server development — Nextcloud latest Developer Manual latest documentation](#server-development-nextcloud-latest-developer-manual-latest-documentation)
- [Unit-Testing — Nextcloud latest Developer Manual latest documentation](#unit-testing-nextcloud-latest-developer-manual-latest-documentation)
- [Back-end code — Nextcloud latest Developer Manual latest documentation](#back-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud architecture — Nextcloud latest Developer Manual latest documentation](#nextcloud-architecture-nextcloud-latest-developer-manual-latest-documentation)
- [External API — Nextcloud latest Developer Manual latest documentation](#external-api-nextcloud-latest-developer-manual-latest-documentation)
- [App development — Nextcloud latest Developer Manual latest documentation](#app-development-nextcloud-latest-developer-manual-latest-documentation)
- [Navigation and pre-app configuration — Nextcloud latest Developer Manual latest documentation](#navigation-and-pre-app-configuration-nextcloud-latest-developer-manual-latest-documentation)
- [Bootstrapping — Nextcloud latest Developer Manual latest documentation](#bootstrapping-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency management — Nextcloud latest Developer Manual latest documentation](#dependency-management-nextcloud-latest-developer-manual-latest-documentation)
- [Translation — Nextcloud latest Developer Manual latest documentation](#translation-nextcloud-latest-developer-manual-latest-documentation)
- [HTML/CSS guidelines — Nextcloud latest Developer Manual latest documentation](#html-css-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Tutorial — Nextcloud latest Developer Manual latest documentation](#tutorial-nextcloud-latest-developer-manual-latest-documentation)
- [How to test … — Nextcloud latest Developer Manual latest documentation](#how-to-test-nextcloud-latest-developer-manual-latest-documentation)
- [Extending the DAV server — Nextcloud latest Developer Manual latest documentation](#extending-the-dav-server-nextcloud-latest-developer-manual-latest-documentation)
- [Development environment — Nextcloud latest Developer Manual latest documentation](#development-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Clients and Client APIs — Nextcloud latest Developer Manual latest documentation](#clients-and-client-apis-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [App metadata — Nextcloud latest Developer Manual latest documentation](#app-metadata-nextcloud-latest-developer-manual-latest-documentation)
- [Desktop Clients — Nextcloud latest Developer Manual latest documentation](#desktop-clients-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end — Nextcloud latest Developer Manual latest documentation](#front-end-nextcloud-latest-developer-manual-latest-documentation)
- [Storage and database — Nextcloud latest Developer Manual latest documentation](#storage-and-database-nextcloud-latest-developer-manual-latest-documentation)
- [Middlewares — Nextcloud latest Developer Manual latest documentation](#middlewares-nextcloud-latest-developer-manual-latest-documentation)
- [Routing — Nextcloud latest Developer Manual latest documentation](#routing-nextcloud-latest-developer-manual-latest-documentation)
- [Logging — Nextcloud latest Developer Manual latest documentation](#logging-nextcloud-latest-developer-manual-latest-documentation)
- [Basic concepts — Nextcloud latest Developer Manual latest documentation](#basic-concepts-nextcloud-latest-developer-manual-latest-documentation)
- [Testing — Nextcloud latest Developer Manual latest documentation](#testing-nextcloud-latest-developer-manual-latest-documentation)
- [Caching — Nextcloud latest Developer Manual latest documentation](#caching-nextcloud-latest-developer-manual-latest-documentation)
- [Public share template — Nextcloud latest Developer Manual latest documentation](#public-share-template-nextcloud-latest-developer-manual-latest-documentation)
- [Background jobs (Cron) — Nextcloud latest Developer Manual latest documentation](#background-jobs-cron-nextcloud-latest-developer-manual-latest-documentation)
- [Translations — Nextcloud latest Developer Manual latest documentation](#translations-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency injection — Nextcloud latest Developer Manual latest documentation](#dependency-injection-nextcloud-latest-developer-manual-latest-documentation)
- [Request lifecycle — Nextcloud latest Developer Manual latest documentation](#request-lifecycle-nextcloud-latest-developer-manual-latest-documentation)
- [Events — Nextcloud latest Developer Manual latest documentation](#events-nextcloud-latest-developer-manual-latest-documentation)
- [Controllers — Nextcloud latest Developer Manual latest documentation](#controllers-nextcloud-latest-developer-manual-latest-documentation)
- [Settings — Nextcloud latest Developer Manual latest documentation](#settings-nextcloud-latest-developer-manual-latest-documentation)
- [Monetizing your app — Nextcloud latest Developer Manual latest documentation](#monetizing-your-app-nextcloud-latest-developer-manual-latest-documentation)
- [Code signing — Nextcloud latest Developer Manual latest documentation](#code-signing-nextcloud-latest-developer-manual-latest-documentation)
- [Release Automation — Nextcloud latest Developer Manual latest documentation](#release-automation-nextcloud-latest-developer-manual-latest-documentation)
- [Building the Client — Nextcloud latest Developer Manual latest documentation](#building-the-client-nextcloud-latest-developer-manual-latest-documentation)
- [Classloader — Nextcloud latest Developer Manual latest documentation](#classloader-nextcloud-latest-developer-manual-latest-documentation)
- [Continuous Integration — Nextcloud latest Developer Manual latest documentation](#continuous-integration-nextcloud-latest-developer-manual-latest-documentation)
- [Deadlocks — Nextcloud latest Developer Manual latest documentation](#deadlocks-nextcloud-latest-developer-manual-latest-documentation)
- [OpenID Connect (Oidc) — Nextcloud latest Developer Manual latest documentation](#openid-connect-oidc-nextcloud-latest-developer-manual-latest-documentation)
- [Debugging — Nextcloud latest Developer Manual latest documentation](#debugging-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud Flow — Nextcloud latest Developer Manual latest documentation](#nextcloud-flow-nextcloud-latest-developer-manual-latest-documentation)
- [Groupware integration — Nextcloud latest Developer Manual latest documentation](#groupware-integration-nextcloud-latest-developer-manual-latest-documentation)
- [Config & Preferences — Nextcloud latest Developer Manual latest documentation](#config-preferences-nextcloud-latest-developer-manual-latest-documentation)
- [NPM — Nextcloud latest Developer Manual latest documentation](#npm-nextcloud-latest-developer-manual-latest-documentation)
- [Out-of-office periods — Nextcloud latest Developer Manual latest documentation](#out-of-office-periods-nextcloud-latest-developer-manual-latest-documentation)
- [API reference — Nextcloud latest Developer Manual latest documentation](#api-reference-nextcloud-latest-developer-manual-latest-documentation)
- [Phone number util — Nextcloud latest Developer Manual latest documentation](#phone-number-util-nextcloud-latest-developer-manual-latest-documentation)
- [Email — Nextcloud latest Developer Manual latest documentation](#email-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Layout — Nextcloud latest Developer Manual latest documentation](#layout-nextcloud-latest-developer-manual-latest-documentation)
- [Layout components — Nextcloud latest Developer Manual latest documentation](#layout-components-nextcloud-latest-developer-manual-latest-documentation)
- [Atomic components — Nextcloud latest Developer Manual latest documentation](#atomic-components-nextcloud-latest-developer-manual-latest-documentation)
- [Notifications — Nextcloud latest Developer Manual latest documentation](#notifications-nextcloud-latest-developer-manual-latest-documentation)
- [HTTP Client — Nextcloud latest Developer Manual latest documentation](#http-client-nextcloud-latest-developer-manual-latest-documentation)
- [JavaScript APIs — Nextcloud latest Developer Manual latest documentation](#javascript-apis-nextcloud-latest-developer-manual-latest-documentation)
- [Repair steps — Nextcloud latest Developer Manual latest documentation](#repair-steps-nextcloud-latest-developer-manual-latest-documentation)
- [Machine Translation — Nextcloud latest Developer Manual latest documentation](#machine-translation-nextcloud-latest-developer-manual-latest-documentation)
- [Open Metrics exporter — Nextcloud latest Developer Manual latest documentation](#open-metrics-exporter-nextcloud-latest-developer-manual-latest-documentation)
- [Profiler — Nextcloud latest Developer Manual latest documentation](#profiler-nextcloud-latest-developer-manual-latest-documentation)
- [Security — Nextcloud latest Developer Manual latest documentation](#security-nextcloud-latest-developer-manual-latest-documentation)
- [Projects — Nextcloud latest Developer Manual latest documentation](#projects-nextcloud-latest-developer-manual-latest-documentation)
- [Dashboard — Nextcloud latest Developer Manual latest documentation](#dashboard-nextcloud-latest-developer-manual-latest-documentation)
- [Foundations — Nextcloud latest Developer Manual latest documentation](#foundations-nextcloud-latest-developer-manual-latest-documentation)
- [Performance considerations — Nextcloud latest Developer Manual latest documentation](#performance-considerations-nextcloud-latest-developer-manual-latest-documentation)
- [Profile — Nextcloud latest Developer Manual latest documentation](#profile-nextcloud-latest-developer-manual-latest-documentation)
- [PSR — Nextcloud latest Developer Manual latest documentation](#psr-nextcloud-latest-developer-manual-latest-documentation)
- [Maintainers — Nextcloud latest Developer Manual latest documentation](#maintainers-nextcloud-latest-developer-manual-latest-documentation)
- [Release process — Nextcloud latest Developer Manual latest documentation](#release-process-nextcloud-latest-developer-manual-latest-documentation)
- [Content list — Nextcloud latest Developer Manual latest documentation](#content-list-nextcloud-latest-developer-manual-latest-documentation)
- [Talk Integration — Nextcloud latest Developer Manual latest documentation](#talk-integration-nextcloud-latest-developer-manual-latest-documentation)
- [Files Metadata — Nextcloud latest Developer Manual latest documentation](#files-metadata-nextcloud-latest-developer-manual-latest-documentation)
- [REST APIs — Nextcloud latest Developer Manual latest documentation](#rest-apis-nextcloud-latest-developer-manual-latest-documentation)
- [Digging deeper — Nextcloud latest Developer Manual latest documentation](#digging-deeper-nextcloud-latest-developer-manual-latest-documentation)
- [Setup checks — Nextcloud latest Developer Manual latest documentation](#setup-checks-nextcloud-latest-developer-manual-latest-documentation)
- [Public Pages — Nextcloud latest Developer Manual latest documentation](#public-pages-nextcloud-latest-developer-manual-latest-documentation)
- [App upgrade guide — Nextcloud latest Developer Manual latest documentation](#app-upgrade-guide-nextcloud-latest-developer-manual-latest-documentation)
- [Main content — Nextcloud latest Developer Manual latest documentation](#main-content-nextcloud-latest-developer-manual-latest-documentation)
- [HTML elements — Nextcloud latest Developer Manual latest documentation](#html-elements-nextcloud-latest-developer-manual-latest-documentation)
- [Icons — Nextcloud latest Developer Manual latest documentation](#icons-nextcloud-latest-developer-manual-latest-documentation)
- [Text-To-Image — Nextcloud latest Developer Manual latest documentation](#text-to-image-nextcloud-latest-developer-manual-latest-documentation)
- [Search — Nextcloud latest Developer Manual latest documentation](#search-nextcloud-latest-developer-manual-latest-documentation)
- [Popover menu — Nextcloud latest Developer Manual latest documentation](#popover-menu-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [CSS — Nextcloud latest Developer Manual latest documentation](#css-nextcloud-latest-developer-manual-latest-documentation)
- [User migration — Nextcloud latest Developer Manual latest documentation](#user-migration-nextcloud-latest-developer-manual-latest-documentation)
- [Web Host Metadata — Nextcloud latest Developer Manual latest documentation](#web-host-metadata-nextcloud-latest-developer-manual-latest-documentation)
- [Reference providers — Nextcloud latest Developer Manual latest documentation](#reference-providers-nextcloud-latest-developer-manual-latest-documentation)
- [Text Processing — Nextcloud latest Developer Manual latest documentation](#text-processing-nextcloud-latest-developer-manual-latest-documentation)
- [Snowflake IDs — Nextcloud latest Developer Manual latest documentation](#snowflake-ids-nextcloud-latest-developer-manual-latest-documentation)
- [Android — Nextcloud latest Developer Manual latest documentation](#android-nextcloud-latest-developer-manual-latest-documentation)
- [Activity — Nextcloud latest Developer Manual latest documentation](#activity-nextcloud-latest-developer-manual-latest-documentation)
- [General — Nextcloud latest Developer Manual latest documentation](#general-nextcloud-latest-developer-manual-latest-documentation)
- [Login Flow — Nextcloud latest Developer Manual latest documentation](#login-flow-nextcloud-latest-developer-manual-latest-documentation)
- [Files — Nextcloud latest Developer Manual latest documentation](#files-nextcloud-latest-developer-manual-latest-documentation)
- [Remote wipe — Nextcloud latest Developer Manual latest documentation](#remote-wipe-nextcloud-latest-developer-manual-latest-documentation)
- [Client Integration — Nextcloud latest Developer Manual latest documentation](#client-integration-nextcloud-latest-developer-manual-latest-documentation)
- [Webdav — Nextcloud latest Developer Manual latest documentation](#webdav-nextcloud-latest-developer-manual-latest-documentation)
- [WebDAV collection preload events — Nextcloud latest Developer Manual latest documentation](#webdav-collection-preload-events-nextcloud-latest-developer-manual-latest-documentation)
- [The Nextcloud app store rules — Nextcloud latest Developer Manual latest documentation](#the-nextcloud-app-store-rules-nextcloud-latest-developer-manual-latest-documentation)
- [Context Chat — Nextcloud latest Developer Manual latest documentation](#context-chat-nextcloud-latest-developer-manual-latest-documentation)
- [OCS API — Nextcloud latest Developer Manual latest documentation](#ocs-api-nextcloud-latest-developer-manual-latest-documentation)
- [Settings — Nextcloud latest Developer Manual latest documentation](#settings-nextcloud-latest-developer-manual-latest-documentation)
- [Speech-To-Text — Nextcloud latest Developer Manual latest documentation](#speech-to-text-nextcloud-latest-developer-manual-latest-documentation)
- [Two-factor providers — Nextcloud latest Developer Manual latest documentation](#two-factor-providers-nextcloud-latest-developer-manual-latest-documentation)
- [Task Processing — Nextcloud latest Developer Manual latest documentation](#task-processing-nextcloud-latest-developer-manual-latest-documentation)
- [User Status — Nextcloud latest Developer Manual latest documentation](#user-status-nextcloud-latest-developer-manual-latest-documentation)
- [Working with time — Nextcloud latest Developer Manual latest documentation](#working-with-time-nextcloud-latest-developer-manual-latest-documentation)
- [User management — Nextcloud latest Developer Manual latest documentation](#user-management-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation](#nextcloud-developer-documentation-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation](#nextcloud-developer-documentation-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation](#nextcloud-developer-documentation-nextcloud-latest-developer-manual-latest-documentation)
- [Desktop Clients — Nextcloud latest Administration Manual latest documentation](#desktop-clients-nextcloud-latest-administration-manual-latest-documentation)
- [Installation and server configuration — Nextcloud latest Administration Manual latest documentation](#installation-and-server-configuration-nextcloud-latest-administration-manual-latest-documentation)
- [Administration privileges (Delegation) — Nextcloud latest Administration Manual latest documentation](#administration-privileges-delegation-nextcloud-latest-administration-manual-latest-documentation)
- [Desktop Clients — Nextcloud latest User Manual latest documentation](#desktop-clients-nextcloud-latest-user-manual-latest-documentation)
- [Prologue — Nextcloud latest Developer Manual latest documentation](#prologue-nextcloud-latest-developer-manual-latest-documentation)
- [Getting started — Nextcloud latest Developer Manual latest documentation](#getting-started-nextcloud-latest-developer-manual-latest-documentation)
- [Prologue — Nextcloud latest Developer Manual latest documentation](#prologue-nextcloud-latest-developer-manual-latest-documentation)
- [Server development — Nextcloud latest Developer Manual latest documentation](#server-development-nextcloud-latest-developer-manual-latest-documentation)
- [ExApp development — Nextcloud latest Developer Manual latest documentation](#exapp-development-nextcloud-latest-developer-manual-latest-documentation)
- [App development — Nextcloud latest Developer Manual latest documentation](#app-development-nextcloud-latest-developer-manual-latest-documentation)
- [Declarative settings — Nextcloud latest Developer Manual latest documentation](#declarative-settings-nextcloud-latest-developer-manual-latest-documentation)
- [App development — Nextcloud latest Developer Manual latest documentation](#app-development-nextcloud-latest-developer-manual-latest-documentation)
- [Basic concepts — Nextcloud latest Developer Manual latest documentation](#basic-concepts-nextcloud-latest-developer-manual-latest-documentation)
- [ExApp development — Nextcloud latest Developer Manual latest documentation](#exapp-development-nextcloud-latest-developer-manual-latest-documentation)
- [Interface & interaction design — Nextcloud latest Developer Manual latest documentation](#interface-interaction-design-nextcloud-latest-developer-manual-latest-documentation)
- [Server development — Nextcloud latest Developer Manual latest documentation](#server-development-nextcloud-latest-developer-manual-latest-documentation)
- [App publishing and maintenance — Nextcloud latest Developer Manual latest documentation](#app-publishing-and-maintenance-nextcloud-latest-developer-manual-latest-documentation)
- [Server development — Nextcloud latest Developer Manual latest documentation](#server-development-nextcloud-latest-developer-manual-latest-documentation)
- [Interface & interaction design — Nextcloud latest Developer Manual latest documentation](#interface-interaction-design-nextcloud-latest-developer-manual-latest-documentation)
- [Code of conduct — Nextcloud latest Developer Manual latest documentation](#code-of-conduct-nextcloud-latest-developer-manual-latest-documentation)
- [App publishing and maintenance — Nextcloud latest Developer Manual latest documentation](#app-publishing-and-maintenance-nextcloud-latest-developer-manual-latest-documentation)
- [Interface & interaction design — Nextcloud latest Developer Manual latest documentation](#interface-interaction-design-nextcloud-latest-developer-manual-latest-documentation)
- [Help and communication — Nextcloud latest Developer Manual latest documentation](#help-and-communication-nextcloud-latest-developer-manual-latest-documentation)
- [Bugtracker — Nextcloud latest Developer Manual latest documentation](#bugtracker-nextcloud-latest-developer-manual-latest-documentation)
- [HTML/CSS guidelines — Nextcloud latest Developer Manual latest documentation](#html-css-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Development process — Nextcloud latest Developer Manual latest documentation](#development-process-nextcloud-latest-developer-manual-latest-documentation)
- [App publishing and maintenance — Nextcloud latest Developer Manual latest documentation](#app-publishing-and-maintenance-nextcloud-latest-developer-manual-latest-documentation)
- [Code of conduct — Nextcloud latest Developer Manual latest documentation](#code-of-conduct-nextcloud-latest-developer-manual-latest-documentation)
- [Compatibility with the app ecosystem — Nextcloud latest Developer Manual latest documentation](#compatibility-with-the-app-ecosystem-nextcloud-latest-developer-manual-latest-documentation)
- [Security guidelines — Nextcloud latest Developer Manual latest documentation](#security-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Clients and Client APIs — Nextcloud latest Developer Manual latest documentation](#clients-and-client-apis-nextcloud-latest-developer-manual-latest-documentation)
- [Coding style & general guidelines — Nextcloud latest Developer Manual latest documentation](#coding-style-general-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [HTML/CSS guidelines — Nextcloud latest Developer Manual latest documentation](#html-css-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [HTML/CSS guidelines — Nextcloud latest Developer Manual latest documentation](#html-css-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Code of conduct — Nextcloud latest Developer Manual latest documentation](#code-of-conduct-nextcloud-latest-developer-manual-latest-documentation)
- [Help and communication — Nextcloud latest Developer Manual latest documentation](#help-and-communication-nextcloud-latest-developer-manual-latest-documentation)
- [Help and communication — Nextcloud latest Developer Manual latest documentation](#help-and-communication-nextcloud-latest-developer-manual-latest-documentation)
- [Bugtracker — Nextcloud latest Developer Manual latest documentation](#bugtracker-nextcloud-latest-developer-manual-latest-documentation)
- [Bugtracker — Nextcloud latest Developer Manual latest documentation](#bugtracker-nextcloud-latest-developer-manual-latest-documentation)
- [Development process — Nextcloud latest Developer Manual latest documentation](#development-process-nextcloud-latest-developer-manual-latest-documentation)
- [Desktop Clients — Nextcloud latest Developer Manual latest documentation](#desktop-clients-nextcloud-latest-developer-manual-latest-documentation)
- [Desktop Clients — Nextcloud latest Developer Manual latest documentation](#desktop-clients-nextcloud-latest-developer-manual-latest-documentation)
- [Clients and Client APIs — Nextcloud latest Developer Manual latest documentation](#clients-and-client-apis-nextcloud-latest-developer-manual-latest-documentation)
- [Clients and Client APIs — Nextcloud latest Developer Manual latest documentation](#clients-and-client-apis-nextcloud-latest-developer-manual-latest-documentation)
- [Development process — Nextcloud latest Developer Manual latest documentation](#development-process-nextcloud-latest-developer-manual-latest-documentation)
- [Security guidelines — Nextcloud latest Developer Manual latest documentation](#security-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Compatibility with the app ecosystem — Nextcloud latest Developer Manual latest documentation](#compatibility-with-the-app-ecosystem-nextcloud-latest-developer-manual-latest-documentation)
- [Compatibility with the app ecosystem — Nextcloud latest Developer Manual latest documentation](#compatibility-with-the-app-ecosystem-nextcloud-latest-developer-manual-latest-documentation)
- [Coding style & general guidelines — Nextcloud latest Developer Manual latest documentation](#coding-style-general-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Development environment — Nextcloud latest Developer Manual latest documentation](#development-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Security guidelines — Nextcloud latest Developer Manual latest documentation](#security-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Coding style & general guidelines — Nextcloud latest Developer Manual latest documentation](#coding-style-general-guidelines-nextcloud-latest-developer-manual-latest-documentation)
- [Development environment — Nextcloud latest Developer Manual latest documentation](#development-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Development environment — Nextcloud latest Developer Manual latest documentation](#development-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Routing — Nextcloud latest Developer Manual latest documentation](#routing-nextcloud-latest-developer-manual-latest-documentation)
- [Request lifecycle — Nextcloud latest Developer Manual latest documentation](#request-lifecycle-nextcloud-latest-developer-manual-latest-documentation)
- [Middlewares — Nextcloud latest Developer Manual latest documentation](#middlewares-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Navigation and pre-app configuration — Nextcloud latest Developer Manual latest documentation](#navigation-and-pre-app-configuration-nextcloud-latest-developer-manual-latest-documentation)
- [Tutorial — Nextcloud latest Developer Manual latest documentation](#tutorial-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end — Nextcloud latest Developer Manual latest documentation](#front-end-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency injection — Nextcloud latest Developer Manual latest documentation](#dependency-injection-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Bootstrapping — Nextcloud latest Developer Manual latest documentation](#bootstrapping-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency management — Nextcloud latest Developer Manual latest documentation](#dependency-management-nextcloud-latest-developer-manual-latest-documentation)
- [Development overview — Nextcloud latest Developer Manual latest documentation](#development-overview-nextcloud-latest-developer-manual-latest-documentation)
- [Technical details — Nextcloud latest Developer Manual latest documentation](#technical-details-nextcloud-latest-developer-manual-latest-documentation)
- [Frequently Asked Questions — Nextcloud latest Developer Manual latest documentation](#frequently-asked-questions-nextcloud-latest-developer-manual-latest-documentation)
- [Routing — Nextcloud latest Developer Manual latest documentation](#routing-nextcloud-latest-developer-manual-latest-documentation)
- [Routing — Nextcloud latest Developer Manual latest documentation](#routing-nextcloud-latest-developer-manual-latest-documentation)
- [App metadata — Nextcloud latest Developer Manual latest documentation](#app-metadata-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Setting up dev environment — Nextcloud latest Developer Manual latest documentation](#setting-up-dev-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Translation setup — Nextcloud latest Developer Manual latest documentation](#translation-setup-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Middlewares — Nextcloud latest Developer Manual latest documentation](#middlewares-nextcloud-latest-developer-manual-latest-documentation)
- [Tutorial — Nextcloud latest Developer Manual latest documentation](#tutorial-nextcloud-latest-developer-manual-latest-documentation)
- [Technical details — Nextcloud latest Developer Manual latest documentation](#technical-details-nextcloud-latest-developer-manual-latest-documentation)
- [Development overview — Nextcloud latest Developer Manual latest documentation](#development-overview-nextcloud-latest-developer-manual-latest-documentation)
- [Development overview — Nextcloud latest Developer Manual latest documentation](#development-overview-nextcloud-latest-developer-manual-latest-documentation)
- [Frequently Asked Questions — Nextcloud latest Developer Manual latest documentation](#frequently-asked-questions-nextcloud-latest-developer-manual-latest-documentation)
- [Frequently Asked Questions — Nextcloud latest Developer Manual latest documentation](#frequently-asked-questions-nextcloud-latest-developer-manual-latest-documentation)
- [Technical details — Nextcloud latest Developer Manual latest documentation](#technical-details-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency injection — Nextcloud latest Developer Manual latest documentation](#dependency-injection-nextcloud-latest-developer-manual-latest-documentation)
- [Background jobs (Cron) — Nextcloud latest Developer Manual latest documentation](#background-jobs-cron-nextcloud-latest-developer-manual-latest-documentation)
- [Translations — Nextcloud latest Developer Manual latest documentation](#translations-nextcloud-latest-developer-manual-latest-documentation)
- [Bootstrapping — Nextcloud latest Developer Manual latest documentation](#bootstrapping-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end — Nextcloud latest Developer Manual latest documentation](#front-end-nextcloud-latest-developer-manual-latest-documentation)
- [Controllers — Nextcloud latest Developer Manual latest documentation](#controllers-nextcloud-latest-developer-manual-latest-documentation)
- [Tutorial — Nextcloud latest Developer Manual latest documentation](#tutorial-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end code — Nextcloud latest Developer Manual latest documentation](#front-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud Assistant — Nextcloud latest Administration Manual latest documentation](#nextcloud-assistant-nextcloud-latest-administration-manual-latest-documentation)
- [Request lifecycle — Nextcloud latest Developer Manual latest documentation](#request-lifecycle-nextcloud-latest-developer-manual-latest-documentation)
- [Request lifecycle — Nextcloud latest Developer Manual latest documentation](#request-lifecycle-nextcloud-latest-developer-manual-latest-documentation)
- [Middlewares — Nextcloud latest Developer Manual latest documentation](#middlewares-nextcloud-latest-developer-manual-latest-documentation)
- [Caching — Nextcloud latest Developer Manual latest documentation](#caching-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Bootstrapping — Nextcloud latest Developer Manual latest documentation](#bootstrapping-nextcloud-latest-developer-manual-latest-documentation)
- [Setting up dev environment — Nextcloud latest Developer Manual latest documentation](#setting-up-dev-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Static analysis — Nextcloud latest Developer Manual latest documentation](#static-analysis-nextcloud-latest-developer-manual-latest-documentation)
- [Setting up dev environment — Nextcloud latest Developer Manual latest documentation](#setting-up-dev-environment-nextcloud-latest-developer-manual-latest-documentation)
- [Back-end code — Nextcloud latest Developer Manual latest documentation](#back-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency injection — Nextcloud latest Developer Manual latest documentation](#dependency-injection-nextcloud-latest-developer-manual-latest-documentation)
- [Navigation and pre-app configuration — Nextcloud latest Developer Manual latest documentation](#navigation-and-pre-app-configuration-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud architecture — Nextcloud latest Developer Manual latest documentation](#nextcloud-architecture-nextcloud-latest-developer-manual-latest-documentation)
- [External API — Nextcloud latest Developer Manual latest documentation](#external-api-nextcloud-latest-developer-manual-latest-documentation)
- [Unit-Testing — Nextcloud latest Developer Manual latest documentation](#unit-testing-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end — Nextcloud latest Developer Manual latest documentation](#front-end-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Navigation and pre-app configuration — Nextcloud latest Developer Manual latest documentation](#navigation-and-pre-app-configuration-nextcloud-latest-developer-manual-latest-documentation)
- [Logging — Nextcloud latest Developer Manual latest documentation](#logging-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency management — Nextcloud latest Developer Manual latest documentation](#dependency-management-nextcloud-latest-developer-manual-latest-documentation)
- [App metadata — Nextcloud latest Developer Manual latest documentation](#app-metadata-nextcloud-latest-developer-manual-latest-documentation)
- [App metadata — Nextcloud latest Developer Manual latest documentation](#app-metadata-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end code — Nextcloud latest Developer Manual latest documentation](#front-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [Back-end code — Nextcloud latest Developer Manual latest documentation](#back-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [Front-end code — Nextcloud latest Developer Manual latest documentation](#front-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [How to test … — Nextcloud latest Developer Manual latest documentation](#how-to-test-nextcloud-latest-developer-manual-latest-documentation)
- [Static analysis — Nextcloud latest Developer Manual latest documentation](#static-analysis-nextcloud-latest-developer-manual-latest-documentation)
- [Static analysis — Nextcloud latest Developer Manual latest documentation](#static-analysis-nextcloud-latest-developer-manual-latest-documentation)
- [Back-end code — Nextcloud latest Developer Manual latest documentation](#back-end-code-nextcloud-latest-developer-manual-latest-documentation)
- [Events — Nextcloud latest Developer Manual latest documentation](#events-nextcloud-latest-developer-manual-latest-documentation)
- [Controllers — Nextcloud latest Developer Manual latest documentation](#controllers-nextcloud-latest-developer-manual-latest-documentation)
- [Extending the DAV server — Nextcloud latest Developer Manual latest documentation](#extending-the-dav-server-nextcloud-latest-developer-manual-latest-documentation)
- [Extending the DAV server — Nextcloud latest Developer Manual latest documentation](#extending-the-dav-server-nextcloud-latest-developer-manual-latest-documentation)
- [Dependency management — Nextcloud latest Developer Manual latest documentation](#dependency-management-nextcloud-latest-developer-manual-latest-documentation)
- [Translation setup — Nextcloud latest Developer Manual latest documentation](#translation-setup-nextcloud-latest-developer-manual-latest-documentation)
- [Translation setup — Nextcloud latest Developer Manual latest documentation](#translation-setup-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud architecture — Nextcloud latest Developer Manual latest documentation](#nextcloud-architecture-nextcloud-latest-developer-manual-latest-documentation)
- [Unit-Testing — Nextcloud latest Developer Manual latest documentation](#unit-testing-nextcloud-latest-developer-manual-latest-documentation)
- [Controllers — Nextcloud latest Developer Manual latest documentation](#controllers-nextcloud-latest-developer-manual-latest-documentation)
- [External API — Nextcloud latest Developer Manual latest documentation](#external-api-nextcloud-latest-developer-manual-latest-documentation)
- [External API — Nextcloud latest Developer Manual latest documentation](#external-api-nextcloud-latest-developer-manual-latest-documentation)
- [Unit-Testing — Nextcloud latest Developer Manual latest documentation](#unit-testing-nextcloud-latest-developer-manual-latest-documentation)
- [Nextcloud architecture — Nextcloud latest Developer Manual latest documentation](#nextcloud-architecture-nextcloud-latest-developer-manual-latest-documentation)
- [How to test … — Nextcloud latest Developer Manual latest documentation](#how-to-test-nextcloud-latest-developer-manual-latest-documentation)
- [Background jobs (Cron) — Nextcloud latest Developer Manual latest documentation](#background-jobs-cron-nextcloud-latest-developer-manual-latest-documentation)
- [Background jobs (Cron) — Nextcloud latest Developer Manual latest documentation](#background-jobs-cron-nextcloud-latest-developer-manual-latest-documentation)
- [Translations — Nextcloud latest Developer Manual latest documentation](#translations-nextcloud-latest-developer-manual-latest-documentation)
- [Storage and database — Nextcloud latest Developer Manual latest documentation](#storage-and-database-nextcloud-latest-developer-manual-latest-documentation)
- [Public share template — Nextcloud latest Developer Manual latest documentation](#public-share-template-nextcloud-latest-developer-manual-latest-documentation)
- [How to test … — Nextcloud latest Developer Manual latest documentation](#how-to-test-nextcloud-latest-developer-manual-latest-documentation)
- [Events — Nextcloud latest Developer Manual latest documentation](#events-nextcloud-latest-developer-manual-latest-documentation)
- [Caching — Nextcloud latest Developer Manual latest documentation](#caching-nextcloud-latest-developer-manual-latest-documentation)
- [Translations — Nextcloud latest Developer Manual latest documentation](#translations-nextcloud-latest-developer-manual-latest-documentation)
- [Events — Nextcloud latest Developer Manual latest documentation](#events-nextcloud-latest-developer-manual-latest-documentation)
- [Logging — Nextcloud latest Developer Manual latest documentation](#logging-nextcloud-latest-developer-manual-latest-documentation)
- [Logging — Nextcloud latest Developer Manual latest documentation](#logging-nextcloud-latest-developer-manual-latest-documentation)
- [Caching — Nextcloud latest Developer Manual latest documentation](#caching-nextcloud-latest-developer-manual-latest-documentation)
- [Testing — Nextcloud latest Developer Manual latest documentation](#testing-nextcloud-latest-developer-manual-latest-documentation)
- [Storage and database — Nextcloud latest Developer Manual latest documentation](#storage-and-database-nextcloud-latest-developer-manual-latest-documentation)
- [Storage and database — Nextcloud latest Developer Manual latest documentation](#storage-and-database-nextcloud-latest-developer-manual-latest-documentation)
- [Public share template — Nextcloud latest Developer Manual latest documentation](#public-share-template-nextcloud-latest-developer-manual-latest-documentation)
- [Testing — Nextcloud latest Developer Manual latest documentation](#testing-nextcloud-latest-developer-manual-latest-documentation)
- [Public share template — Nextcloud latest Developer Manual latest documentation](#public-share-template-nextcloud-latest-developer-manual-latest-documentation)
- [Testing — Nextcloud latest Developer Manual latest documentation](#testing-nextcloud-latest-developer-manual-latest-documentation)
- [Settings — Nextcloud latest Developer Manual latest documentation](#settings-nextcloud-latest-developer-manual-latest-documentation)
- [ExApp development — Nextcloud latest Developer Manual latest documentation](#exapp-development-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Foundations — Nextcloud latest Developer Manual latest documentation](#foundations-nextcloud-latest-developer-manual-latest-documentation)
- [Layout — Nextcloud latest Developer Manual latest documentation](#layout-nextcloud-latest-developer-manual-latest-documentation)
- [Settings — Nextcloud latest Developer Manual latest documentation](#settings-nextcloud-latest-developer-manual-latest-documentation)
- [Atomic components — Nextcloud latest Developer Manual latest documentation](#atomic-components-nextcloud-latest-developer-manual-latest-documentation)
- [Layout components — Nextcloud latest Developer Manual latest documentation](#layout-components-nextcloud-latest-developer-manual-latest-documentation)
- [Maintainers — Nextcloud latest Developer Manual latest documentation](#maintainers-nextcloud-latest-developer-manual-latest-documentation)
- [Monetizing your app — Nextcloud latest Developer Manual latest documentation](#monetizing-your-app-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Layout — Nextcloud latest Developer Manual latest documentation](#layout-nextcloud-latest-developer-manual-latest-documentation)
- [Building the Client — Nextcloud latest Developer Manual latest documentation](#building-the-client-nextcloud-latest-developer-manual-latest-documentation)
- [Building the Client — Nextcloud latest Developer Manual latest documentation](#building-the-client-nextcloud-latest-developer-manual-latest-documentation)
- [Release process — Nextcloud latest Developer Manual latest documentation](#release-process-nextcloud-latest-developer-manual-latest-documentation)
- [Foundations — Nextcloud latest Developer Manual latest documentation](#foundations-nextcloud-latest-developer-manual-latest-documentation)
- [Layout — Nextcloud latest Developer Manual latest documentation](#layout-nextcloud-latest-developer-manual-latest-documentation)
- [Foundations — Nextcloud latest Developer Manual latest documentation](#foundations-nextcloud-latest-developer-manual-latest-documentation)
- [Code signing — Nextcloud latest Developer Manual latest documentation](#code-signing-nextcloud-latest-developer-manual-latest-documentation)
- [Release Automation — Nextcloud latest Developer Manual latest documentation](#release-automation-nextcloud-latest-developer-manual-latest-documentation)
- [App upgrade guide — Nextcloud latest Developer Manual latest documentation](#app-upgrade-guide-nextcloud-latest-developer-manual-latest-documentation)
- [Layout components — Nextcloud latest Developer Manual latest documentation](#layout-components-nextcloud-latest-developer-manual-latest-documentation)
- [Layout components — Nextcloud latest Developer Manual latest documentation](#layout-components-nextcloud-latest-developer-manual-latest-documentation)
- [Atomic components — Nextcloud latest Developer Manual latest documentation](#atomic-components-nextcloud-latest-developer-manual-latest-documentation)
- [Getting started — Nextcloud latest Developer Manual latest documentation](#getting-started-nextcloud-latest-developer-manual-latest-documentation)
- [Getting started — Nextcloud latest Developer Manual latest documentation](#getting-started-nextcloud-latest-developer-manual-latest-documentation)
- [Main content — Nextcloud latest Developer Manual latest documentation](#main-content-nextcloud-latest-developer-manual-latest-documentation)
- [Atomic components — Nextcloud latest Developer Manual latest documentation](#atomic-components-nextcloud-latest-developer-manual-latest-documentation)
- [Icons — Nextcloud latest Developer Manual latest documentation](#icons-nextcloud-latest-developer-manual-latest-documentation)
- [Content list — Nextcloud latest Developer Manual latest documentation](#content-list-nextcloud-latest-developer-manual-latest-documentation)
- [Maintainers — Nextcloud latest Developer Manual latest documentation](#maintainers-nextcloud-latest-developer-manual-latest-documentation)
- [Maintainers — Nextcloud latest Developer Manual latest documentation](#maintainers-nextcloud-latest-developer-manual-latest-documentation)
- [HTML elements — Nextcloud latest Developer Manual latest documentation](#html-elements-nextcloud-latest-developer-manual-latest-documentation)
- [Popover menu — Nextcloud latest Developer Manual latest documentation](#popover-menu-nextcloud-latest-developer-manual-latest-documentation)
- [Settings — Nextcloud latest Developer Manual latest documentation](#settings-nextcloud-latest-developer-manual-latest-documentation)
- [Monetizing your app — Nextcloud latest Developer Manual latest documentation](#monetizing-your-app-nextcloud-latest-developer-manual-latest-documentation)
- [Release process — Nextcloud latest Developer Manual latest documentation](#release-process-nextcloud-latest-developer-manual-latest-documentation)
- [App upgrade guide — Nextcloud latest Developer Manual latest documentation](#app-upgrade-guide-nextcloud-latest-developer-manual-latest-documentation)
- [Monetizing your app — Nextcloud latest Developer Manual latest documentation](#monetizing-your-app-nextcloud-latest-developer-manual-latest-documentation)
- [App upgrade guide — Nextcloud latest Developer Manual latest documentation](#app-upgrade-guide-nextcloud-latest-developer-manual-latest-documentation)
- [Release process — Nextcloud latest Developer Manual latest documentation](#release-process-nextcloud-latest-developer-manual-latest-documentation)
- [Release Automation — Nextcloud latest Developer Manual latest documentation](#release-automation-nextcloud-latest-developer-manual-latest-documentation)
- [Code signing — Nextcloud latest Developer Manual latest documentation](#code-signing-nextcloud-latest-developer-manual-latest-documentation)
- [Code signing — Nextcloud latest Developer Manual latest documentation](#code-signing-nextcloud-latest-developer-manual-latest-documentation)
- [Release Automation — Nextcloud latest Developer Manual latest documentation](#release-automation-nextcloud-latest-developer-manual-latest-documentation)
- [Android — Nextcloud latest Developer Manual latest documentation](#android-nextcloud-latest-developer-manual-latest-documentation)
- [Main content — Nextcloud latest Developer Manual latest documentation](#main-content-nextcloud-latest-developer-manual-latest-documentation)
- [General — Nextcloud latest Developer Manual latest documentation](#general-nextcloud-latest-developer-manual-latest-documentation)
- [Activity — Nextcloud latest Developer Manual latest documentation](#activity-nextcloud-latest-developer-manual-latest-documentation)
- [Main content — Nextcloud latest Developer Manual latest documentation](#main-content-nextcloud-latest-developer-manual-latest-documentation)
- [Prologue — Nextcloud latest Developer Manual latest documentation](#prologue-nextcloud-latest-developer-manual-latest-documentation)
- [CSS — Nextcloud latest Developer Manual latest documentation](#css-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Files — Nextcloud latest Developer Manual latest documentation](#files-nextcloud-latest-developer-manual-latest-documentation)
- [Popover menu — Nextcloud latest Developer Manual latest documentation](#popover-menu-nextcloud-latest-developer-manual-latest-documentation)
- [Content list — Nextcloud latest Developer Manual latest documentation](#content-list-nextcloud-latest-developer-manual-latest-documentation)
- [Content list — Nextcloud latest Developer Manual latest documentation](#content-list-nextcloud-latest-developer-manual-latest-documentation)
- [Remote wipe — Nextcloud latest Developer Manual latest documentation](#remote-wipe-nextcloud-latest-developer-manual-latest-documentation)
- [Icons — Nextcloud latest Developer Manual latest documentation](#icons-nextcloud-latest-developer-manual-latest-documentation)
- [Icons — Nextcloud latest Developer Manual latest documentation](#icons-nextcloud-latest-developer-manual-latest-documentation)
- [Webdav — Nextcloud latest Developer Manual latest documentation](#webdav-nextcloud-latest-developer-manual-latest-documentation)
- [Login Flow — Nextcloud latest Developer Manual latest documentation](#login-flow-nextcloud-latest-developer-manual-latest-documentation)
- [Popover menu — Nextcloud latest Developer Manual latest documentation](#popover-menu-nextcloud-latest-developer-manual-latest-documentation)
- [HTML elements — Nextcloud latest Developer Manual latest documentation](#html-elements-nextcloud-latest-developer-manual-latest-documentation)
- [HTML elements — Nextcloud latest Developer Manual latest documentation](#html-elements-nextcloud-latest-developer-manual-latest-documentation)
- [CSS — Nextcloud latest Developer Manual latest documentation](#css-nextcloud-latest-developer-manual-latest-documentation)
- [CSS — Nextcloud latest Developer Manual latest documentation](#css-nextcloud-latest-developer-manual-latest-documentation)
- [General — Nextcloud latest Developer Manual latest documentation](#general-nextcloud-latest-developer-manual-latest-documentation)
- [General — Nextcloud latest Developer Manual latest documentation](#general-nextcloud-latest-developer-manual-latest-documentation)
- [Activity — Nextcloud latest Developer Manual latest documentation](#activity-nextcloud-latest-developer-manual-latest-documentation)
- [App development — Nextcloud latest Developer Manual latest documentation](#app-development-nextcloud-latest-developer-manual-latest-documentation)
- [Android — Nextcloud latest Developer Manual latest documentation](#android-nextcloud-latest-developer-manual-latest-documentation)
- [Remote wipe — Nextcloud latest Developer Manual latest documentation](#remote-wipe-nextcloud-latest-developer-manual-latest-documentation)
- [Android — Nextcloud latest Developer Manual latest documentation](#android-nextcloud-latest-developer-manual-latest-documentation)
- [Activity — Nextcloud latest Developer Manual latest documentation](#activity-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [Login Flow — Nextcloud latest Developer Manual latest documentation](#login-flow-nextcloud-latest-developer-manual-latest-documentation)
- [Login Flow — Nextcloud latest Developer Manual latest documentation](#login-flow-nextcloud-latest-developer-manual-latest-documentation)
- [Files — Nextcloud latest Developer Manual latest documentation](#files-nextcloud-latest-developer-manual-latest-documentation)
- [Remote wipe — Nextcloud latest Developer Manual latest documentation](#remote-wipe-nextcloud-latest-developer-manual-latest-documentation)
- [Webdav — Nextcloud latest Developer Manual latest documentation](#webdav-nextcloud-latest-developer-manual-latest-documentation)
- [Files — Nextcloud latest Developer Manual latest documentation](#files-nextcloud-latest-developer-manual-latest-documentation)
- [Webdav — Nextcloud latest Developer Manual latest documentation](#webdav-nextcloud-latest-developer-manual-latest-documentation)
- [Introduction — Nextcloud latest Developer Manual latest documentation](#introduction-nextcloud-latest-developer-manual-latest-documentation)
- [The Nextcloud app store rules — Nextcloud latest Developer Manual latest documentation](#the-nextcloud-app-store-rules-nextcloud-latest-developer-manual-latest-documentation)
- [The Nextcloud app store rules — Nextcloud latest Developer Manual latest documentation](#the-nextcloud-app-store-rules-nextcloud-latest-developer-manual-latest-documentation)
- [The Nextcloud app store rules — Nextcloud latest Developer Manual latest documentation](#the-nextcloud-app-store-rules-nextcloud-latest-developer-manual-latest-documentation)
- [Digging deeper — Nextcloud latest Developer Manual latest documentation](#digging-deeper-nextcloud-latest-developer-manual-latest-documentation)
- [OCS API — Nextcloud latest Developer Manual latest documentation](#ocs-api-nextcloud-latest-developer-manual-latest-documentation)
- [OCS API — Nextcloud latest Developer Manual latest documentation](#ocs-api-nextcloud-latest-developer-manual-latest-documentation)
---
# Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/#)
* Nextcloud developer documentation
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/index.rst)
* * *
Nextcloud developer documentation[](https://docs.nextcloud.com/server/latest/developer_manual/#nextcloud-developer-documentation "Link to this heading")
==========================================================================================================================================================
Table of contents[](https://docs.nextcloud.com/server/latest/developer_manual/#table-of-contents "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------
* [Prologue](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html)
* [Code of conduct](https://docs.nextcloud.com/server/latest/developer_manual/prologue/code-of-conduct.html)
* [Help and communication](https://docs.nextcloud.com/server/latest/developer_manual/prologue/help_communication.html)
* [Bugtracker](https://docs.nextcloud.com/server/latest/developer_manual/prologue/bugtracker/index.html)
* [Security guidelines](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html)
* [Compatibility with the app ecosystem](https://docs.nextcloud.com/server/latest/developer_manual/prologue/compatibility_app_ecosystem.html)
* [Getting started](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/index.html)
* [Development process](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html)
* [Development environment](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/devenv.html)
* [Coding style & general guidelines](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/latest/developer_manual/basics/index.html)
* [Request lifecycle](https://docs.nextcloud.com/server/latest/developer_manual/basics/request_lifecycle.html)
* [Routing](https://docs.nextcloud.com/server/latest/developer_manual/basics/routing.html)
* [Dependency injection](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html)
* [Controllers](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html)
* [Middlewares](https://docs.nextcloud.com/server/latest/developer_manual/basics/middlewares.html)
* [Events](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html)
* [Front-end](https://docs.nextcloud.com/server/latest/developer_manual/basics/front-end/index.html)
* [Translations](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html)
* [Background jobs (Cron)](https://docs.nextcloud.com/server/latest/developer_manual/basics/backgroundjobs.html)
* [Caching](https://docs.nextcloud.com/server/latest/developer_manual/basics/caching.html)
* [Logging](https://docs.nextcloud.com/server/latest/developer_manual/basics/logging.html)
* [Settings](https://docs.nextcloud.com/server/latest/developer_manual/basics/setting.html)
* [Storage and database](https://docs.nextcloud.com/server/latest/developer_manual/basics/storage/index.html)
* [Public share template](https://docs.nextcloud.com/server/latest/developer_manual/basics/public_share_template.html)
* [Testing](https://docs.nextcloud.com/server/latest/developer_manual/basics/testing.html)
* [App development](https://docs.nextcloud.com/server/latest/developer_manual/app_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/app_development/intro.html)
* [Tutorial](https://docs.nextcloud.com/server/latest/developer_manual/app_development/tutorial.html)
* [Bootstrapping](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html)
* [App metadata](https://docs.nextcloud.com/server/latest/developer_manual/app_development/info.html)
* [Navigation and pre-app configuration](https://docs.nextcloud.com/server/latest/developer_manual/app_development/init.html)
* [Dependency management](https://docs.nextcloud.com/server/latest/developer_manual/app_development/dependency_management.html)
* [Extending the DAV server](https://docs.nextcloud.com/server/latest/developer_manual/app_development/dav_extension.html)
* [Translation](https://docs.nextcloud.com/server/latest/developer_manual/app_development/translation.html)
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/Introduction.html)
* [Setting up dev environment](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html)
* [Development overview](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/index.html)
* [Technical details](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/index.html)
* [Frequently Asked Questions](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/index.html)
* [Server development](https://docs.nextcloud.com/server/latest/developer_manual/server/index.html)
* [Front-end code](https://docs.nextcloud.com/server/latest/developer_manual/server/code-front-end.html)
* [Back-end code](https://docs.nextcloud.com/server/latest/developer_manual/server/code-back-end.html)
* [Static analysis](https://docs.nextcloud.com/server/latest/developer_manual/server/static-analysis.html)
* [Unit-Testing](https://docs.nextcloud.com/server/latest/developer_manual/server/unit-testing.html)
* [External API](https://docs.nextcloud.com/server/latest/developer_manual/server/externalapi.html)
* [Nextcloud architecture](https://docs.nextcloud.com/server/latest/developer_manual/server/architecture/index.html)
* [How to test …](https://docs.nextcloud.com/server/latest/developer_manual/how_to/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* [API reference](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/api.html)
* [Config & Preferences](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/index.html)
* [Classloader](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/classloader.html)
* [Context Chat](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html)
* [Continuous Integration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/continuous_integration.html)
* [Dashboard](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html)
* [Deadlocks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html)
* [Debugging](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html)
* [Email](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/email.html)
* [Files Metadata](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html)
* [Groupware integration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/index.html)
* [HTTP Client](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html)
* [JavaScript APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html)
* [Machine Translation](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/machinetranslation.html)
* [Nextcloud Flow](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/flow.html)
* [NPM](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html)
* [Notifications](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/notifications.html)
* [OpenID Connect (Oidc)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/oidc.html)
* [Out-of-office periods](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/out_of_office.html)
* [Open Metrics exporter](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/openmetrics.html)
* [Performance considerations](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html)
* [Phone number util](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/phonenumberutil.html)
* [PSR](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html)
* [Profile](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profile.html)
* [Profiler](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html)
* [Projects](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/projects.html)
* [Public Pages](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html)
* [Reference providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html)
* [Repair steps](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/repair.html)
* [REST APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html)
* [Search](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html)
* [Security](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/security.html)
* [Settings](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html)
* [Setup checks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html)
* [Snowflake IDs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html)
* [Speech-To-Text](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html)
* [Talk Integration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html)
* [Task Processing](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html)
* [Text Processing](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html)
* [Text-To-Image](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html)
* [Two-factor providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html)
* [User Status](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/status.html)
* [User migration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/user_migration.html)
* [User management](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html)
* [Web Host Metadata](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html)
* [WebDAV collection preload events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html)
* [Working with time](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/time.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/index.html)
* [Maintainers](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/maintainer.html)
* [Release process](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html)
* [Publishing App on the App Store](https://nextcloudappstore.readthedocs.io/en/latest/developer.html)
* [Monetizing your app](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/monetizing.html)
* [The Nextcloud app store rules](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html)
* [Code signing](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/code_signing.html)
* [Release Automation](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_automation.html)
* [App upgrade guide](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html)
* [Interface & interaction design](https://docs.nextcloud.com/server/latest/developer_manual/design/index.html)
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html)
* [Layout](https://docs.nextcloud.com/server/latest/developer_manual/design/layout.html)
* [Layout components](https://docs.nextcloud.com/server/latest/developer_manual/design/layoutcomponents.html)
* [Atomic components](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html)
* [New button](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#new-button)
* [App navigation menu](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#app-navigation-menu)
* [Settings](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#settings)
* [Main content](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/content.html)
* [Content list](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/list.html)
* [Popover menu](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html)
* [HTML elements](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/html.html)
* [CSS](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html)
* [Icons](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/icons.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* [General](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/general.html)
* [Activity](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/activity-api.html)
* [Android](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/android_library/index.html)
* [Files](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/files.html)
* [Login Flow](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html)
* [OCS API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/index.html)
* [Remote wipe](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/RemoteWipe/index.html)
* [Webdav](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/index.html)
* [Client Integration](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html)
* [Desktop Clients](https://docs.nextcloud.com/server/latest/developer_manual/desktop/index.html)
* [Building the Client](https://docs.nextcloud.com/server/latest/developer_manual/desktop/building.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Development process — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Getting started](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/index.html)
* Development process
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/getting_started/development_process.rst)
* * *
Development process[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#development-process "Link to this heading")
======================================================================================================================================================================
This page gives an overview of how Nextcloud code is developed.
Source Code Version Control[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#source-code-version-control "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nextcloud uses [git](https://git-scm.com/)
to manage revisions of the code. Software components have their own repositories.
### Branch Names[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#branch-names "Link to this heading")
Default branches of Nextcloud and its app repositories are named `main` or `master`. Additionally, there are _stable branches_ whenever a major version of Nextcloud is released. Those are named `stableX`, where X refers to the version. For Nextcloud 25, for example, the stable branch is named `stable25`.
Target Branches for Contributions[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#target-branches-for-contributions "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Any changes made to the source code go into the default branch of a repository through a [pull request](https://docs.github.com/en/pull-requests)
.
\# Switch to the default branch and update it
git checkout main
git pull origin main
\# Create the new feature branch
git checkout \-b feature/foo-bar
\# Add and commit the changes
git add file1 file2
git commit \--signoff \-m 'Add foo bar'
\# Push the new commit to the remote repository and open a pull request
git push origin feature/foo-bar
### Bugfixes[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#bugfixes "Link to this heading")
If a contribution fixes a bug that also affects older Nextcloud or app releases, it may qualify for a _backport_. Backporting a fix means applying the change on an older version of the code. Git calls this operation _cherry picking_.
#### Automatic Backport[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#automatic-backport "Link to this heading")
In many cases the cherry pick results in a clean apply of the patch and git is able to resolve any small conflicts. In those cases it’s easiest to let the [backport bot](https://github.com/nextcloud/backportbot)
do the backport.
See the [bot usage](https://github.com/nextcloud/backportbot#usage)
for its commands.
#### Manual Backport[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#manual-backport "Link to this heading")
More complex changes may require the developer to do the backport manually. This can be done as follows:
\# Switch to the target branch and update it
git checkout stable25
git pull origin stable25
\# Create the new backport branch
git checkout \-b fix/foo-stable25
\# Cherry pick the change from the commit sha1 of the change against the default branch
\# This might cause conflicts. Resolve them.
git cherry-pick abc123
\# Push the cherry pick commit to the remote repository and open a pull request
git push origin fix/foo-stable25
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Coding style & general guidelines — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Getting started](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/index.html)
* Coding style & general guidelines
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/getting_started/coding_standards/index.rst)
* * *
Coding style & general guidelines[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#coding-style-general-guidelines "Link to this heading")
===================================================================================================================================================================================================
General[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#general "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------
* Ideally, discuss your plans on the [forums](https://help.nextcloud.com/)
to see if others want to work with you on it
* We use [GitHub](https://github.com/nextcloud)
, please get an account there and clone the repositories you want to work on
* Fixes go directly to the main branch, nevertheless they need to be tested thoroughly.
* New features are always developed in a branch and only merged to the main branch once they are fully done.
* Software should work. We only put features into the main branch when they are complete. It’s better to not have a feature instead of having one that works poorly.
* It is best to start working based on an issue - create one if there is none. You describe what you want to do, ask feedback on the direction you take it and take it from there.
* When you are finished, use the merge request function on GitHub to create a pull request. The other developers will look at it and give you feedback. You can signify that your PR is ready for review by adding the label “3. to review” to it. See [the code review page for more information](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/prologue/bugtracker/codereviews.html)
* It is key to keep changes separate and small. The bigger and more hairy a PR grows, the harder it is to get it in. So split things up where you can in smaller changes - if you need a small improvement like a API addition for a big feature addition, get it in first rather than adding it to the big piece of work!
* Decisions are made by consensus. We strive for making the best technical decisions and as nobody can know everything, we collaborate. That means a first negative comment might not be the final word, neither is positive feedback an immediate GO. Nextcloud is built out of modular pieces (apps) and maintainers have a strong influence. In case of disagreement we consult other seasoned contributors.
Labels[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#labels "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
We assign labels to issues and pull requests to make it easy to find them and to signal what needs to be done. Some of these are assigned by the developers, others by QA, bug triagers, project lead or maintainers and so on. It is not desired that users/reporters of bugs assign labels themselves, unless they are developers/contributors to Nextcloud.
The most important labels and their meaning:
* Tags showing the state of the issue or PR, numbered 0-4:
* `0. to triage` - issue or feature request needs to get triaged and approved for development
* `1. to develop` - ready to start development on this
* `2. developing` - development in progress
* `3. to review` - ready for review
* `4. to release` - reviewed PR that awaits unfreeze of a branch to get merged or has pending CI jobs
* `needs info` - this issue needs further information from the reporter, see [Nextcloud bug triaging](https://docs.nextcloud.com/server/latest/developer_manual/prologue/bugtracker/triaging.html)
. This tag is typically combined with `0. to triage` to signal a bug report is not confirmed yet or a feature request has not been approved.
* `needs review` - this issue needs further investigation from the Nextcloud team, see [Nextcloud bug triaging](https://docs.nextcloud.com/server/latest/developer_manual/prologue/bugtracker/triaging.html)
.
* Tags showing the type of issue or PR
* `bug` - this issue is a bug
* `enhancement` - this issue is a feature request/idea for improvement of Nextcloud
* `technical debt` - this issue or PR is about [technical debt](https://en.wikipedia.org/wiki/Technical_debt)
* `overview` - this issue is a summary of a global effort, usually referencing other issues
* Tags that classify an issue or PR
* `high`, `medium` and `low` – signify how important the bug is.
* `regression` - something that worked in a previous release but is now not working as expected or missing.
* `feature: *`, e.g. `feature: dav` – these tags group tickets of specific feature or subsystems.
* `design` - this needs help from the design team or is a design-related issue/pull request
* `good first issue` - these are issues which are relatively easy to solve and ideal for people who want to learn how to code in Nextcloud
* `backport-request` - the pull requests also needs to be applied to older Nextcloud versions. This tag is typically assigned by automation.
User interface[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#user-interface "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
* Software should get out of the way. Do things automatically instead of offering configuration options.
* Software should be easy to use. Show only the most important elements. Secondary elements only on hover or via Advanced function.
* User data is sacred. Provide undo instead of asking for confirmation - [which might be dismissed](http://www.alistapart.com/articles/neveruseawarning/)
* The state of the application should be clear. If something loads, provide feedback.
* Do not adapt broken concepts (for example design of desktop apps) just for the sake of consistency. We aim to provide a better interface, so let’s find out how to do that!
* Regularly reset your installation to see how the first-run experience is like. And improve it.
* Ideally do [usability testing](http://jancborchardt.net/usability-in-free-software)
to know how people use the software.
* For further UX principles, read [Alex Faaborg from Mozilla](http://uxmag.com/articles/quantifying-usability)
.
Coding standards[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#coding-standards "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Maximum line-length of 80 characters
* Use tabs to indent
* A tab is 4 spaces wide
* Opening braces of blocks are on the same line as the definition
* Quotes: ‘ for everything, “ for HTML attributes (
)
* End of Lines : Unix style (LF / ‘n’) only
* No global variables or functions
* Code should be tested, ideally with unit and integration tests.
* When you `git pull`, always `git pull --rebase` to avoid generating extra commits like: _merged main into main_
The most part of Nextcloud is written in PHP, Typescript / JavaScript, so we have some more fine grained coding standards for those languages:
* [PHP coding standards](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/php.html)
* [JavaScript and Typescript](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/javascript.html)
* [CSS and HTML coding standards](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/html_css.html)
License headers[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#license-headers "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
Nextcloud is licensed under the [GNU Affero General Public License v3.0](https://www.gnu.org/licenses/agpl)
. From 16 June 2016, we switched to “GNU Affero General Public License v3.0 or later” for better long-term maintainability.
If you create a new file please use this header:
/\*\*
\* SPDX-FileCopyrightText: \[year\] \[your name\] \[\]
\* SPDX-License-Identifier: AGPL-3.0-or-later
\*/
The year should then be the creation time and the email address is optional.
If you edit an existing file please, please keep the existing license header as it is and just add your copyright notice, if you consider your changes substantial enough to claim copyright.
In order to do so there are two options:
* If a generic header is already present, please just add yourself to the AUTHORS.md file
* If no generic header is present, you can add yourself with a copyright line as described above. As a rule of thumb, this is the case if you contributed more than seven lines of code.
An example of a generic license header where adding yourself to the AUTHORS.md file is preferred please see the example below
/\*\*
\* SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors
\* SPDX-License-Identifier: AGPL-3.0-or-later
\*/
The Nextcloud GmbH part only applies to employees of the company not to contributors.
For more, general information on SPDX headers and their usage for reuse-compliance, please see
* [REUSE](https://reuse.software/)
* [SPDX](https://spdx.dev/)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Prologue — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* Prologue
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/index.rst)
* * *
Prologue[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html#prologue "Link to this heading")
===========================================================================================================================
* [Code of conduct](https://docs.nextcloud.com/server/latest/developer_manual/prologue/code-of-conduct.html)
* [Help and communication](https://docs.nextcloud.com/server/latest/developer_manual/prologue/help_communication.html)
* [Forums](https://docs.nextcloud.com/server/latest/developer_manual/prologue/help_communication.html#forums)
* [Maintainers](https://docs.nextcloud.com/server/latest/developer_manual/prologue/help_communication.html#maintainers)
* [Bugtracker](https://docs.nextcloud.com/server/latest/developer_manual/prologue/bugtracker/index.html)
* [Security guidelines](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html)
* [SQL injection](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#sql-injection)
* [Cross site scripting](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#cross-site-scripting)
* [Clickjacking](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#clickjacking)
* [Code executions / file inclusions](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#code-executions-file-inclusions)
* [Directory traversal](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#directory-traversal)
* [Shell injection](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#shell-injection)
* [Auth bypass / privilege escalations](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#auth-bypass-privilege-escalations)
* [Sensitive data exposure](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#sensitive-data-exposure)
* [Cross site request forgery](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#cross-site-request-forgery)
* [Unvalidated redirects](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#unvalidated-redirects)
* [CORS](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#cors)
* [Getting help](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#getting-help)
* [Compatibility with the app ecosystem](https://docs.nextcloud.com/server/latest/developer_manual/prologue/compatibility_app_ecosystem.html)
* [Documentation procedures of changes that affect app developers](https://docs.nextcloud.com/server/latest/developer_manual/prologue/compatibility_app_ecosystem.html#documentation-procedures-of-changes-that-affect-app-developers)
* [Other documentation requirements](https://docs.nextcloud.com/server/latest/developer_manual/prologue/compatibility_app_ecosystem.html#other-documentation-requirements)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Interface & interaction design — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* Interface & interaction design
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/design/index.rst)
* * *
Interface & interaction design[](https://docs.nextcloud.com/server/latest/developer_manual/design/index.html#interface-interaction-design "Link to this heading")
===================================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html)
* [Color](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#color)
* [Typography](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#typography)
* [Icons](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#icons)
* [Naming](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#naming)
* [Wording](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#wording)
* [Layout](https://docs.nextcloud.com/server/latest/developer_manual/design/layout.html)
* [Navigation → Content → Sidebar](https://docs.nextcloud.com/server/latest/developer_manual/design/layout.html#navigation-content-sidebar)
* [Navigation → List → Content](https://docs.nextcloud.com/server/latest/developer_manual/design/layout.html#navigation-list-content)
* [Layout components](https://docs.nextcloud.com/server/latest/developer_manual/design/layoutcomponents.html)
* [Navigation](https://docs.nextcloud.com/server/latest/developer_manual/design/layoutcomponents.html#navigation)
* [List item](https://docs.nextcloud.com/server/latest/developer_manual/design/layoutcomponents.html#list-item)
* [Content](https://docs.nextcloud.com/server/latest/developer_manual/design/layoutcomponents.html#content)
* [Sidebar](https://docs.nextcloud.com/server/latest/developer_manual/design/layoutcomponents.html#sidebar)
* [Atomic components](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html)
* [Buttons](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#buttons)
* [Action menu](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#action-menu)
* [Input fields](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#input-fields)
* [Pickers](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#pickers)
* [Tags](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#tags)
* [Modal](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#modal)
* [Avatar](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#avatar)
* [Progress bars and meters](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#progress-bars-and-meters)
* [User bubbles](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#user-bubbles)
* [Counter bubbles](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#counter-bubbles)
* [Empty content](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#empty-content)
* [Skeleton screens](https://docs.nextcloud.com/server/latest/developer_manual/design/atomiccomponents.html#skeleton-screens)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Code of conduct — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html)
* Code of conduct
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/code-of-conduct.rst)
* * *
Code of conduct[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/code-of-conduct.html#code-of-conduct "Link to this heading")
===================================================================================================================================================
We want the Nextcloud community to be a fun and productive environment for everyone. For that reason, we ask all contributors and participants to familiarize themselves with our [Code of Conduct](https://nextcloud.com/code-of-conduct)
.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Getting started — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* Getting started
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/getting_started/index.rst)
* * *
Getting started[](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/index.html#getting-started "Link to this heading")
================================================================================================================================================
* [Development process](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html)
* [Source Code Version Control](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#source-code-version-control)
* [Target Branches for Contributions](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/development_process.html#target-branches-for-contributions)
* [Development environment](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/devenv.html)
* [Set up Web server and database](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/devenv.html#set-up-web-server-and-database)
* [Get the source](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/devenv.html#get-the-source)
* [Coding style & general guidelines](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html)
* [General](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#general)
* [Labels](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#labels)
* [User interface](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#user-interface)
* [Coding standards](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#coding-standards)
* [License headers](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/coding_standards/index.html#license-headers)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# ExApp development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* ExApp development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/index.rst)
* * *
ExApp development[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/index.html#exapp-development "Link to this heading")
======================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/Introduction.html)
* [Overview](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/Introduction.html#overview)
* [Glossary](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/Introduction.html#glossary)
* [Setting up dev environment](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html)
* [Install AppAPI](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#install-appapi)
* [In Place of a Conclusion](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#in-place-of-a-conclusion)
* [Development overview](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/index.html)
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html)
* [ExApp overview](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppOverview.html)
* [ExApp lifecycle](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppLifecycle.html)
* [Adapting ExApps to HaRP](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppHarpIntegration.html)
* [Technical details](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/index.html)
* [App Installation Flow](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/InstallationFlow.html)
* [Deployment](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html)
* [Authentication](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Authentication.html)
* [Translations](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html)
* [AppAPI Nextcloud APIs](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/index.html)
* [Frequently Asked Questions](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/index.html)
* [Docker Container Registry](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerContainerRegistry.html)
* [Docker Socket Proxy](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerSocketProxy.html)
* [GPU support](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/GpuSupport.html)
* [Scaling](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Scaling.html)
* [Corporate Proxy - Permanent Settings for PHP CLI](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/BehindCompanyProxy.html)
* [Troubleshooting](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Troubleshooting.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Development overview — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/index.html)
* Development overview
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/development_overview/index.rst)
* * *
Development overview[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/index.html#development-overview "Link to this heading")
=================================================================================================================================================================================
This section contains the most common information for ExApp developers, grouped from other parts of documentation.
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html)
* [0\. Setting up the development environment](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html#setting-up-the-development-environment)
* [1\. Starting from template](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html#starting-from-template)
* [3\. Development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html#development)
* [4\. Packaging](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html#packaging)
* [5\. AppStore publishing](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html#appstore-publishing)
* [6\. Testing](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html#testing)
* [ExApp overview](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppOverview.html)
* [ExApp structure](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppOverview.html#exapp-structure)
* [Backend](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppOverview.html#backend)
* [Frontend](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppOverview.html#frontend)
* [L10n translations](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppOverview.html#l10n-translations)
* [Makefile](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppOverview.html#makefile)
* [ExApp lifecycle](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppLifecycle.html)
* [ExApp lifecycle methods](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppLifecycle.html#exapp-lifecycle-methods)
* [ExApp lifecycle scheme](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppLifecycle.html#exapp-lifecycle-scheme)
* [Nextcloud-side ExApp lifecycle methods](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppLifecycle.html#nextcloud-side-exapp-lifecycle-methods)
* [AppAPI Authentication](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppLifecycle.html#appapi-authentication)
* [Adapting ExApps to HaRP](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppHarpIntegration.html)
* [Summary](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppHarpIntegration.html#summary)
* [Key integration considerations](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppHarpIntegration.html#key-integration-considerations)
* [Steps needed to adapt an ExApp](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppHarpIntegration.html#steps-needed-to-adapt-an-exapp)
* [Running your ExApp with a non-root user](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppHarpIntegration.html#running-your-exapp-with-a-non-root-user)
* [Integration test example](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/development_overview/ExAppHarpIntegration.html#integration-test-example)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Technical details — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/index.html)
* Technical details
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/tech_details/index.rst)
* * *
Technical details[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/index.html#technical-details "Link to this heading")
===================================================================================================================================================================
* [App Installation Flow](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/InstallationFlow.html)
* [Image Pulling (Docker)](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/InstallationFlow.html#image-pulling-docker)
* [Heartbeat](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/InstallationFlow.html#heartbeat)
* [Init](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/InstallationFlow.html#init)
* [Enabled](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/InstallationFlow.html#enabled)
* [Deployment](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html)
* [Overview](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html#overview)
* [DaemonConfig registration](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html#daemonconfig-registration)
* [ExApp registration](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html#exapp-registration)
* [Application installation scheme](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html#application-installation-scheme)
* [ExApp info.xml schema](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html#exapp-info-xml-schema)
* [Authentication](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Authentication.html)
* [Authentication flow](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Authentication.html#authentication-flow)
* [Authentication headers](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Authentication.html#authentication-headers)
* [AppAPIAuth](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Authentication.html#appapiauth)
* [AppAPI session keys](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Authentication.html#appapi-session-keys)
* [Translations](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html)
* [Front-end](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html#front-end)
* [Back-end](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html#back-end)
* [Manual translations](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html#manual-translations)
* [Manual install](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html#manual-install)
* [Docker install](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html#docker-install)
* [Translation tool](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Translations.html#translation-tool)
* [AppAPI Nextcloud APIs](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/index.html)
* [Logging](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/logging.html)
* [AppConfig](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/appconfig.html)
* [Preferences](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/preferences.html)
* [ExApp](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/exapp.html)
* [Routes](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/routes.html)
* [Miscellaneous OCS APIs](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/utils.html)
* [File Actions Menu](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/fileactionsmenu.html)
* [Top Menu Entry](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/topmenu.html)
* [Declarative Settings](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/settings.html)
* [Notifications](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/notifications.html)
* [Events Listener](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/events_listener.html)
* [OCC Command](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/occ_command.html)
* [Talk bots](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/talkbots.html)
* [Other OCS APIs](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/api/other_ocs.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Compatibility with the app ecosystem — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html)
* Compatibility with the app ecosystem
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/compatibility_app_ecosystem.rst)
* * *
Compatibility with the app ecosystem[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/compatibility_app_ecosystem.html#compatibility-with-the-app-ecosystem "Link to this heading")
=========================================================================================================================================================================================================
The Nextcloud app ecosystem consists of hundreds of apps and app maintainers.
The development process may require changes that affect apps in this ecosystem. These changes may either be a change in standards or best practises, yet in more extreme cases the changes may also be breaking apps.
While developers are expected to aim for limiting the number of changes that break apps, this cannot always be avoided or is not always reasonable to do to maintain an up-to-date technology stack.
Informing app developers about any change that affect them is therefore key to a thriving ecosystem. This page describes the three procedures to document changes that are relevant to app developers.
Documentation procedures of changes that affect app developers[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/compatibility_app_ecosystem.html#documentation-procedures-of-changes-that-affect-app-developers "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are three procedures in place to facilitate communication to app developers about changes that affect them:
1. The definition of **Done** of a pull request includes documentation.
> This means the development of your pull request cannot be considered done if you introduced changes (additions, removals or modifications) that affect app developers that you did not document.
2. A change that affects app developers, has to be reported and documented by the author of the pull request in the [App Upgrade guide](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html#app-upgrade-guide)
section.
> The requirements for this documentation are:
>
> * It should be written so that app developers understand how to work around the change for their app in a tutorial format
>
> * The steps should be explicitly written, so the documentation shall not rely upon links to external resources for the steps. While it is encouraged to add an external links as additional reference, it is a hard requirement that the documentation is readable and actionable without browsing to this link.
>
> * The change author’s name should be added to the section so readers can reach out to the author if they have questions or if something is unclear.
>
> * Timeline: the documentation is required to be handed in when finalizing the pull request and should be merged timely close to the actual change.
>
Other documentation requirements[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/compatibility_app_ecosystem.html#other-documentation-requirements "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A change that affects administrators who upgrade their Nextcloud should be documented in the release notes section of the admin documentation of that release.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Help and communication — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html)
* Help and communication
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/help_communication.rst)
* * *
Help and communication[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/help_communication.html#help-and-communication "Link to this heading")
====================================================================================================================================================================
Forums[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/help_communication.html#forums "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------
Communicate via our [forums](https://help.nextcloud.com/)
.
Maintainers[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/help_communication.html#maintainers "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------
* [Contact](https://nextcloud.com/contact/)
a maintainer of a certain app or division
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Bugtracker — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html)
* Bugtracker
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/bugtracker/index.rst)
* * *
Bugtracker[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/bugtracker/index.html#bugtracker "Link to this heading")
==========================================================================================================================================
Thank you for helping Nextcloud by reporting bugs. Before submitting an issue, please read [Issue submission guidelines](https://github.com/nextcloud/server/blob/master/.github/CONTRIBUTING.md#submitting-issues)
first.
* If the issue is with the Nextcloud server, report it to the [Server repository](https://github.com/nextcloud/server/issues)
* If the issue is with the Nextcloud desktop client, report it to the [Desktop repository](https://github.com/nextcloud/desktop/issues)
* If the issue is with the Nextcloud Android client, report it to the [Android repository](https://github.com/nextcloud/android/issues)
* If the issue is with the Nextcloud iOS client, report it to the [iOS repository](https://github.com/nextcloud/ios/issues)
* If the issue is with a Nextcloud app, report it to where that app is developed. See [App Store](https://apps.nextcloud.com/)
page for related links.
* If the app is listed in our [main GitHub organization](https://github.com/nextcloud)
report it to the correct sub repository
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Introduction — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/index.html)
* Introduction
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/Introduction.rst)
* * *
Introduction[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/Introduction.html#introduction "Link to this heading")
===================================================================================================================================================
**ExApps** (short for “External Apps”) are Nextcloud apps that are developed in another programming language (outside of PHP) using the AppAPI OCS API. [AppAPI](https://apps.nextcloud.com/apps/app_api)
is a project introduced by Nextcloud to revolutionize the process of application development within the Nextcloud ecosystem.
Overview[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/Introduction.html#overview "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------
The main tasks of the AppAPI ecosystem are:
> * Providing a reliable and fast method for authenticating applications
>
> * Supporting various application deployment options
>
> * Offering a clear and straightforward application administration interface
>
> * Ensuring a reliable implementation of all the necessary missing APIs for applications
>
> * Supplying clear, understandable documentation and support on how to implement libraries in other programming languages for writing next-gen applications for Nextcloud
>
The system should support the expansion and integration of new deployment methods, avoiding any tight coupling with a specific deployment type. Applications should be capable of indicating the deployment methods they can accommodate.
Given the evolving landscape of new technologies and the potential emergence of more intricate or simplified deployment options, the system is architected to seamlessly embrace the integration of novel deployment modes.
If you have any questions or corrections regarding the documentation, we would be glad to address them in discussions, incorporate corrections through pull requests, and handle complex problems through issues.
Glossary[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/Introduction.html#glossary "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------
AppAPI brings out the following terms frequently used in the code:
* `ExApp` (External App) - the app on another (from PHP) programming language, which uses AppAPI OCS API
* `DaemonConfig` - configuration of orchestration daemon (e.g. Docker) where ExApps are deployed
* `DeployConfig` - additional DaemonConfig options for orchestrator (e.g. network) and ExApps (nextcloud\_url, host, etc.)
* `ExAppConfig` - similar to Nextcloud app\_config, but for ExApps configuration
* `ExAppPreferences` - similar to Nextcloud app\_preferences, user-specific settings for ExApps
* `AppAPIAuth` - AppAPI authentication
* `FileActionsMenu` - entry in files actions menu (context menu)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Frequently Asked Questions — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/index.html)
* Frequently Asked Questions
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/faq/index.rst)
* * *
Frequently Asked Questions[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/index.html#frequently-asked-questions "Link to this heading")
============================================================================================================================================================================
This section contains the most common or problematic questions that users or developers may encounter when working with AppAPI. It can be used as pointer to other parts of the documentation, as it usually refers to, or provide a brief answer.
Note
This section will be updated with time, as new questions arise. If you have a question that is not listed here or the answer is not enough for you, please feel free to ask it by creating an issue in the [AppAPI repository](https://github.com/nextcloud/app_api/issues)
.
* [Docker Container Registry](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerContainerRegistry.html)
* [How to use a private Docker container registry with authentication?](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerContainerRegistry.html#how-to-use-a-private-docker-container-registry-with-authentication)
* [Docker Socket Proxy](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerSocketProxy.html)
* [Nextcloud AppAPI DSP](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerSocketProxy.html#nextcloud-appapi-dsp)
* [Nextcloud AIO](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerSocketProxy.html#nextcloud-aio)
* [Other implementations](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/DockerSocketProxy.html#other-implementations)
* [GPU support](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/GpuSupport.html)
* [How to enable GPU support for the Deploy daemon?](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/GpuSupport.html#how-to-enable-gpu-support-for-the-deploy-daemon)
* [How to limit the number of GPUs per ExApp?](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/GpuSupport.html#how-to-limit-the-number-of-gpus-per-exapp)
* [Scaling](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Scaling.html)
* [GPUs scaling](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Scaling.html#gpus-scaling)
* [Corporate Proxy - Permanent Settings for PHP CLI](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/BehindCompanyProxy.html)
* [Symptoms](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/BehindCompanyProxy.html#symptoms)
* [Cause](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/BehindCompanyProxy.html#cause)
* [Permanent Solution](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/BehindCompanyProxy.html#permanent-solution)
* [Troubleshooting](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/BehindCompanyProxy.html#troubleshooting)
* [Contact Support](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/BehindCompanyProxy.html#contact-support)
* [Troubleshooting](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Troubleshooting.html)
* [How to troubleshoot networking issues?](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Troubleshooting.html#how-to-troubleshoot-networking-issues)
* [ExApp deployment issues](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Troubleshooting.html#exapp-deployment-issues)
* [Failed to create volume](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Troubleshooting.html#failed-to-create-volume)
* [ExApps management list of apps from App Store is empty](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/faq/Troubleshooting.html#exapps-management-list-of-apps-from-app-store-is-empty)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Setting up dev environment — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [ExApp development](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/index.html)
* Setting up dev environment
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/DevSetup.rst)
* * *
Setting up dev environment[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#setting-up-dev-environment "Link to this heading")
===========================================================================================================================================================================
AppAPI development requires a Nextcloud development environment setup. We highly recommend using [Julius Knorr’s Docker setup](https://github.com/juliusknorr/nextcloud-docker-dev)
for this. For an alternate environment without using Docker, please refer to the setup instructions in [Getting started](https://docs.nextcloud.com/server/latest/developer_manual/getting_started/devenv.html)
.
Suggested IDE: **PhpStorm**, though you can certainly use any IDE of your preference such as **VS Code** or **Vim**.
Install AppAPI[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#install-appapi "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------
All ExApps require the [AppAPI](https://apps.nextcloud.com/apps/app_api)
Nextcloud app as a dependency. As of Nextcloud version 30.0.1, AppAPI is automatically installed by default. If you prefer, you can also build the latest development version of AppAPI from the source code, in which case uninstall the release version of AppAPI and perform the following steps.
Clone the latest main branch:
> git clone https://github.com/nextcloud/app\_api.git && cd app\_api
or clone a specific version by specifying the version tag:
> git clone https://github.com/nextcloud/app\_api.git \--branch && cd app\_api
where `` is the version you want to install.
Then, build frontend assets in development mode:
> npm ci && npm run dev
Enable AppAPI from the directory where the `occ` command resides:
> ./occ app:enable \--force app\_api
### Deploy daemons types[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#deploy-daemons-types "Link to this heading")
There are two types of Deploy daemons that can be used for development and testing of ExApps:
1. `manual_install`: This type of Deploy daemon is running manually in the host machine. This is useful for ExApp development as you can run your ExApp directly on the host.
2. `docker_install`: This type of Deploy daemon is running in a Docker container.
You can register (create) these daemons in the AppAPI admin settings. For the equivalent `occ` command or an explanation of the Deploy daemon parameters, see [DaemonConfig registration](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/tech_details/Deployment.html#occ-daemon-config-registration)
.
### Docker Socket Proxy[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#docker-socket-proxy "Link to this heading")
For development and testing locally, the simplest way is to use the [Nextcloud AppAPI DSP HTTP](https://github.com/nextcloud/docker-socket-proxy?tab=readme-ov-file#httplocal)
.
In Place of a Conclusion[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#in-place-of-a-conclusion "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are several make commands available to ease frequent development actions.
To see the complete list, execute `make help`.
### Docker remote API[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#docker-remote-api "Link to this heading")
The Docker Engine remote API can be easily configured via `make dock2port` command. The command will create a docker container to provide remote Docker Engine API.
Afterward, register DaemonConfigs in Nextcloud using `make dock-port` command.
### Docker by socket[](https://docs.nextcloud.com/server/latest/developer_manual/exapp_development/DevSetup.html#docker-by-socket "Link to this heading")
For Docker via socket, use the command `make dock-sock`. This registers DaemonConfigs in Nextcloud for the default socket connection (`/var/run/docker.sock`).
Make sure that socket has enough permissions for Nextcloud and webserver user to access it and actually forwarded to the container:
...
volumes:
...
\- /var/run/docker.sock:/var/run/docker.sock
...
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Security guidelines — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html)
* Security guidelines
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/security.rst)
* * *
Security guidelines[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#security-guidelines "Link to this heading")
====================================================================================================================================================
This guideline highlights some of the most common security problems and how to prevent them. Please review your app if it contains any of the following security holes.
Note
**Program defensively**: for instance always check for CSRF or escape strings, even if you do not need it. This prevents future problems where you might miss a change that leads to a security hole.
Note
All App Framework security features depend on the call of the controller through `OCA\AppFramework\App::main`. If the controller method is executed directly, no security checks are being performed!
SQL injection[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#sql-injection "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------
[SQL Injection](https://en.wikipedia.org/wiki/SQL_injection)
occurs when SQL query strings are concatenated with variables.
To prevent this, always use prepared queries:
execute($params);
If the App Framework is used, write SQL queries like this in a class that extends the Mapper:
execute($sql, $params);
Cross site scripting[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#cross-site-scripting "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
[Cross site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting)
happens when user input is passed directly to templates. A potential attacker might be able to inject HTML/JavaScript into the page to steal the users session, log keyboard entries, even perform DDOS attacks on other websites or other malicious actions.
Despite the fact that Nextcloud uses Content-Security-Policy to prevent the execution of inline JavaScript code developers are still required to prevent XSS. CSP is just another layer of defense that is not implemented in all web browsers.
To prevent XSS in your app you have to sanitize the templates and all JavaScripts which performs a DOM manipulation.
### Templates[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#templates "Link to this heading")
Let’s assume you use the following example in your application:
to overtake the user account. The same problem occurs when outputting content from the database or any other location that is writable by users.
Another attack vector that is often overlooked is XSS in **href** attributes. HTML allows to execute JavaScript in href attributes like this:
To prevent XSS in your app, **never use echo, print() or <%=** - use **p()** instead which will sanitize the input. Also **validate URLs to start with the expected protocol** (starts with http for instance)!
Note
Should you ever require to print something unescaped, double check if it is really needed. If there is no other way (e.g. when including of subtemplates) use print\_unescaped with care.
### JavaScript[](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#javascript "Link to this heading")
Avoid manipulating the HTML directly via JavaScript, this often leads to XSS since people often forget to sanitize variables:
var html \= '
Add a **non-breaking space** before the triple-dot when trimming a sentence instead of a word. |
| `Loading …`
(a general space `U+0020`) | `Loading …`
(a non-breaking space `U+00A0`) | Only use a **non-breaking space** before the triple-dot (`U+00A0`). |
| Don’t | Do not | Using the spelled out version is easier to understand and makes translating easier. |
| Won’t | Will not | Using the spelled out version is easier to understand and makes translating easier. |
| Can not | Cannot | Using the combined version is easier to understand and makes translating easier. |
| id | ID | Full uppercase for shortcutting “identifier” |
| Users | Accounts / People | Use **accounts** when you refer to a profile/entity. Use **people** when referring to humans. |
| Admin / Administrator | Administration | Refer to administration as a non-human organizational entity
instead of a single or multiple persons. |
| Headline | Headline: | Include colons `:` in the translations as some languages add a space before the colon. |
| “ Leading space”
“Trailing space “ | “No leading space”
“No trailing space” | Leading or trailing spaces mostly indicate that strings are concatenated.
For translators it is often helpful to have all the content in a single translation,
as order and references between words and sentences might get lost otherwise. |
| “Error:” $error | “Error: %s” | Instead of concatenating errors or part messages, make them a proper placeholder |
### Correct plurals[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#correct-plurals "Link to this heading")
If you use a plural, you **must** also use the `%n` placeholder. The placeholder defines the plural and the word without the number preceding is wrong. If you don’t know/have a number for your translation, e.g. because you don’t know how many items are going to be selected, just use an undefined plural. They exist in every language and have one form. They do not follow the normal plural pattern.
PHP Example:
// BAD: Plural without count
$title \= $l\->n('Import calendar', 'Import calendars', $selectionLength)
// BETTER: Plural has count, but disrupting to read and unnecessary information
$title \= $l\->n('Import %n calendar', 'Import %n calendars', $selectionLength)
// BEST: Simple string with undefined plural not using any number in the string
$title \= $l\->t('Import calendars')
Opposed to the normal placeholders in javascript, the plural number also uses the `%n` syntax:
JS Example:
/\* BAD: Plural without count \*/
n('myapp', 'Import calendar', 'Import calendars', selected.length)
/\* BETTER: Plural has count, but disrupting to read and unnecessary information \*/
n('myapp', 'Import %n calendar', 'Import %n calendars', selected.length)
/\* BEST: Simple string with undefined plural not using any number in the string \*/
t('myapp', 'Import calendars')
### Improving your translations[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#improving-your-translations "Link to this heading")
Starting with the following example, improving it step by step:
t('Select file from')) . ' '; ?>t('local filesystem'));?>t(' or ')); ?>t('cloud'));?>
#### Step 1: String split[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#step-1-string-split "Link to this heading")
You shall **never split** sentences and **never concatenate** two translations (e.g. “Enable” and “dark mode” can not be combined to “Enable dark mode”, because languages might have to use different cases)! Translators lose the context and they have no chance to possibly re-arrange words/parts as needed.
Translators will translate:
* `Select file from`
* `local filesystem`
* `or` (with leading and trailing whitespace)
* `cloud`
Translating these individual strings results in `local filesystem` and `cloud` losing case. The two white spaces surrounding `or` will get lost while translating as well. For languages that have a different grammatical order it prevents the translators from reordering the sentence components.
So the following code is a bit better, but suffers from another issue:
t('Select file from local filesystem or cloud'));?>
#### Step 2: HTML Markup[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#step-2-html-markup "Link to this heading")
In this case the translators can re-arrange as they like, but have to deal with your markup and can mess it up easily. It is better to **keep the markup out** of your code, so the following translation is even better:
t('Select file from %slocal filesystem%s or %scloud%s', \['', '', '', ''\]));?>
But there is one last problem with this.
#### Step 3: Placeholders[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#step-3-placeholders "Link to this heading")
In case the language has to turn things around, your code will still insert the parameters in the given order and they can not re-order them. To prevent this last hurdle simply **use positioned placeholders** like `%1$s`:
t('Select file from %1$slocal filesystem%2$s or %3$scloud%4$s', \['', '', '', ''\]));?>
This allows translators to have the cloudlink before the browselink in case the language is e.g. right-to-left.
### Provide context hints for translators[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#provide-context-hints-for-translators "Link to this heading")
In case some translation strings may be translated wrongly because they have multiple meanings. Especially translations strings that only contain a single word often result in problems. The most famous example in the Nextcloud code base is `Share` which can which can be the verb and action `To share something` or the noun `A share`. The added hints will be shown in the Transifex web-interface:
#### PHP[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#php "Link to this heading")
t('Add new file'));
?>
#### JavaScript / TypeScript[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#javascript-typescript "Link to this heading")
// TRANSLATORS name that is appended to copied files with the same name, will be put in parenthesis and appended with a number if it is the second+ copy
var copyNameLocalized \= t('files', 'copy');
#### Vue[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#vue "Link to this heading")
This covers vue html templates in vue sfc components. For vue js code, see the javascript section.
{{ t('forms', 'Required') }}
#### C++ (Qt) / Desktop client[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#c-qt-desktop-client "Link to this heading")
//: Example text: "Progress of sync process. Shows the currently synced filename"
fileProgressString \= tr("Syncing %1").arg(allFilenames);
#### Android[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#android "Link to this heading")
Boards
#### iOS[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#ios "Link to this heading")
/\* The title on the navigation bar of the Scanning screen. \*/
"wescan.scanning.title" \= "Scanning";
Adding translations[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#adding-translations "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
The steps how to set up translations for an app have been moved to it’s own page in the “App development” chapter: [Translation](https://docs.nextcloud.com/server/latest/developer_manual/app_development/translation.html#translation)
Testing translations[](https://docs.nextcloud.com/server/latest/developer_manual/basics/translations.html#testing-translations "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------
You can use the query parameter `forceLanguage` to force a specific language for a web request (API or frontend). See [Forcing language for a given call](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#api-force-language)
.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Dependency injection — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/latest/developer_manual/basics/index.html)
* Dependency injection
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/dependency_injection.rst)
* * *
Dependency injection[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#dependency-injection "Link to this heading")
================================================================================================================================================================
The App Framework assembles the application by using a container based on the software pattern [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection)
. This makes the code easier to test and thus easier to maintain.
If you are unfamiliar with this pattern, watch the following video:
* [Google Clean Code Talks](https://www.youtube.com/watch?v=RlfLCWKxHJ0)
Dependency injection[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2 "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
Dependency Injection sounds pretty complicated but it just means: Don’t put new dependencies in your constructor or methods but pass them in. So this:
use OCP\\IDBConnection;
// without dependency injection
class AuthorMapper {
private IDBConnection $db;
public function \_\_construct() {
$this\->db \= new Db();
}
}
would turn into this by using Dependency Injection:
use OCP\\IDBConnection;
// with dependency injection
class AuthorMapper {
private IDBConnection $db;
public function \_\_construct(IDBConnection $db) {
$this\->db \= $db;
}
}
Controller injection[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#controller-injection "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
For controllers it’s possible to also have dependencies injected into methods.
lib/Controller/ApiController.php[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id4 "Link to this code")
foo(); }
public function bar(BarService $service) { $service\->bar(); }
}
Using a container[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#using-a-container "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
Note
Please do use automatic dependency injection (see below). For most apps there is no need to register services manually.
Passing dependencies into the constructor rather than instantiating them in the constructor has the following drawback: Every line in the source code where **new AuthorMapper** is being used has to be changed, once a new constructor argument is being added to it.
The solution for this particular problem is to limit the **new AuthorMapper** to one file, the container. The container contains all the factories for creating these objects and is configured in `lib/AppInfo/Application.php`.
Nextcloud 20 and later uses the [PSR-11 standard](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr11)
for the container interface, so working with the container might feel familiar if you’ve worked with other php applications before that also adhere to the convention.
To add the app’s classes simply open the `lib/AppInfo/Application.php` and use the **IRegistrationContext::registerService** method:
registerService(AuthorController::class, function(ContainerInterface $c): AuthorController {
return new AuthorController(
$c\->get('appName'),
$c\->get(Request::class),
$c\->get(AuthorService::class)
);
});
/\*\*
\* Services
\*/
$context\->registerService(AuthorService::class, function(ContainerInterface $c): AuthorService {
return new AuthorService(
$c\->get(AuthorMapper::class)
);
});
/\*\*
\* Mappers
\*/
$context\->registerService(AuthorMapper::class, function(ContainerInterface $c): AuthorMapper {
return new AuthorMapper(
$c\->get(IDBConnection::class)
);
});
}
}
How the container works[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#how-the-container-works "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------
The container works in the following way:
* [A request comes in and is matched against a route](https://docs.nextcloud.com/server/latest/developer_manual/basics/routing.html)
(for the AuthorController in this case)
* The matched route queries **AuthorController** service from the container:
return new AuthorController(
$c->get('appName'),
$c->get(Request::class),
$c->get(AuthorService::class)
);
* The **appName** is queried and returned from the base class
* The **Request** is queried and returned from the server container
* **AuthorService** is queried:
$container->registerService(AuthorService::class, function(ContainerInterface $c): AuthorService {
return new AuthorService(
$c->get(AuthorMapper::class)
);
});
* **AuthorMapper** is queried:
$container->registerService(AuthorMappers::class, function(ContainerInterface $c): AuthorMapper {
return new AuthorService(
$c->get(IDBConnection::class)
);
});
* The **database connection** is returned from the server container
* Now **AuthorMapper** has all of its dependencies and the object is returned
* **AuthorService** gets the **AuthorMapper** and returns the object
* **AuthorController** gets the **AuthorService** and finally the controller can be instantiated and the object is returned
So basically the container is used as a giant factory to build all the classes that are needed for the application. Because it centralizes all the creation of objects (the **new Class()** lines), it is very easy to add new constructor parameters without breaking existing code: only the **\_\_construct** method and the container line where the **new** is being called need to be changed.
Use automatic dependency assembly (recommended)[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#use-automatic-dependency-assembly-recommended "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In Nextcloud it is possible to build classes and their dependencies without having to explicitly register them on the container, as long as the container can [reflect](https://www.php.net/manual/en/book.reflection.php)
the constructor and look up the parameters by their type. This concept is widely known as _auto-wiring_.
### How does auto-wiring work[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#how-does-auto-wiring-work "Link to this heading")
Automatic assembly creates new instances of classes just by looking at the class name and its constructor parameters. For each constructor parameter the type or the argument name is used to query the container, e.g.:
* **SomeType $type** will use **$container->get(SomeType::class)**
* **$variable** will use **$container->get(‘variable’)**
If all constructor parameters are resolved, the class will be created, saved as a service and returned.
So basically the following is now possible:
class \= $class;
$this\->appName \= $appName;
}
}
$app \= new \\OCP\\AppFramework\\App('myapp');
$class2 \= $app\->getContainer()\->get(MyTestClass2::class);
$class2 instanceof MyTestClass2; // true
$class2\->class instanceof MyTestClass; // true
$class2\->appName \=== 'myname'; // true
$class2 \=== $app\->getContainer()\->get(MyTestClass2::class); // true
Note
$appName is resolved because the container registered a parameter under the key ‘appName’ which will return the app id.
### How does it affect the request lifecycle[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#how-does-it-affect-the-request-lifecycle "Link to this heading")
* A request comes in
* All apps’ **routes.php** files are loaded
* If a **routes.php** file returns an array, and an **appname/lib/AppInfo/Application.php** exists, include it, create a new instance of **\\OCA\\AppName\\AppInfo\\Application.php** and register the routes on it. That way a container can be used while still benefitting from the new routes behavior
* If a **routes.php** file returns an array, but there is no **appname/lib/AppInfo/Application.php**, create a new \\OCP\\AppFramework\\App instance with the app id and register the routes on it
* A request is matched for the route, e.g. with the name **page#index**
* The appropriate container is being queried for the entry PageController (to keep backwards compatibility)
* If the entry does not exist, the container is queried for OCA\\AppName\\Controller\\PageController and if no entry exists, the container tries to create the class by using [reflection](https://www.php.net/manual/en/book.reflection.php)
on its constructor parameters
### How does this affect controllers[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#how-does-this-affect-controllers "Link to this heading")
The only thing that needs to be done to add a route and a controller method is now:
**myapp/appinfo/routes.php**
\[\
\['name' \=> 'page#index', 'url' \=> '/', 'verb' \=> 'GET'\],\
\]\];
**myapp/appinfo/lib/Controller/PageController.php**
registerParameter('TableName', 'my\_app\_table');
// the interface is called IAuthorMapper and AuthorMapper implements it
$context\->registerService(IAuthorMapper::class, function (ContainerInterface $c): AuthorMapper {
return $c\->get(AuthorMapper::class);
});
// Less verbose alternative
$context\->registerServiceAlias(IAuthorMapper::class, AuthorMapper::class);
}
}
### Predefined core services[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#predefined-core-services "Link to this heading")
The following parameter names and type hints can be used to inject core services instead of using **$container->getServer()->getServiceX()**
Parameters:
* **appName**: The app id
* **userId**: The id of the current user
* **webRoot**: The path to the Nextcloud installation
Aliases:
* **AppName**: resolves to `appName` (deprecated)
* **Request**: resolves to `\OCP\IRequest`
* **ServerContainer**: resolves to `\OCP\IServerContainer` (deprecated)
* **UserId**: resolves to `userId` (deprecated)
* **WebRoot**: resolves to `webRoot` (deprecated)
Types:
* `\OCP\IAppConfig`
* `\OCP\IAppManager`
* `\OCP\IAvatarManager`
* `\OCP\Activity\IManager`
* `\OCP\ICache`
* `\OCP\ICacheFactory`
* `\OCP\IConfig`
* `\OCP\AppFramework\Utility\IControllerMethodReflector`
* `\OCP\Contacts\IManager`
* `\OCP\IDateTimeZone`
* `\OCP\IDBConnection`
* `\OCP\Diagnostics\IEventLogger`
* `\OCP\Diagnostics\IQueryLogger`
* `\OCP\Files\Config\IMountProviderCollection`
* `\OCP\Files\IRootFolder`
* `\OCP\IGroupManager`
* `\OCP\IL10N`
* `\OCP\BackgroundJob\IJobList`
* `\OCP\INavigationManager`
* `\OCP\IPreview`
* `\OCP\IRequest`
* `\OCP\AppFramework\Utility\ITimeFactory`
* `\OCP\ITagManager`
* `\OCP\ITempManager`
* `\OCP\Route\IRouter`
* `\OCP\ISearch`
* `\OCP\Security\ICrypto`
* `\OCP\Security\IHasher`
* `\OCP\Security\ISecureRandom`
* `\OCP\IURLGenerator`
* `\OCP\IUserManager`
* `\OCP\IUserSession`
* `\Psr\Container\ContainerInterface`
* `\Psr\Log\LoggerInterface`
### How to enable it[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#how-to-enable-it "Link to this heading")
To make use of this new feature, the following things have to be done:
* **appinfo/info.xml** requires to provide another field called **namespace** where the namespace of the app is defined. The required namespace is the one which comes after the top level namespace **OCA\\**, e.g.: for **OCA\\MyBeautifulApp\\Some\\OtherClass** the needed namespace would be **MyBeautifulApp** and would be added to the info.xml in the following way:
MyBeautifulApp
* **appinfo/routes.php**: Instead of creating a new Application class instance, simply return the routes array like:
\[\
\['name' \=> 'page#index', 'url' \=> '/', 'verb' \=> 'GET'\],\
\]\];
Note
A namespace tag is required because you can not deduce the namespace from the app id
Which classes should be added[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#which-classes-should-be-added "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In general all of the app’s controllers need to be registered inside the container. Then the following question is: What goes into the constructor of the controller? Pass everything into the controller constructor that matches one of the following criteria:
* It does I/O (database, write/read to files)
* It is a global (e.g. $\_POST, etc. This is in the request class by the way)
* The output does not depend on the input variables (also called [impure function](https://en.wikipedia.org/wiki/Pure_function)
), e.g. time, random number generator
* It is a service, basically it would make sense to swap it out for a different object
What not to inject:
* It is pure data and has methods that only act upon it (arrays, data objects)
* It is a [pure function](https://en.wikipedia.org/wiki/Pure_function)
Optional services[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#optional-services "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
Added in version 28.
If an injected dependency can’t be found or build, an exception is thrown. This can be avoided by using the a nullable type notation for a dependency:
namespace OCA\\MyApp\\MyService;
use Some\\Service;
class MyService {
public function \_\_construct(private ?Service $service) { }
}
If `\Some\Service` exists and can be built, it will be injected. Else `MyService` will receive `null`.
Accessing the container from anywhere[](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#accessing-the-container-from-anywhere "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sometimes it can be hard to inject some service inside legacy code, in these cases you can use `OCPServer::get(MyService::class)`. This should only be used as the last resort, as this makes your code more complicated to unit test and is considered an anti-pattern.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Request lifecycle — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/latest/developer_manual/basics/index.html)
* Request lifecycle
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/request_lifecycle.rst)
* * *
Request lifecycle[](https://docs.nextcloud.com/server/latest/developer_manual/basics/request_lifecycle.html#request-lifecycle "Link to this heading")
=======================================================================================================================================================
A typical HTTP request consists of the following:
* **A URL**: e.g. /index.php/apps/myapp/something
* **Request Parameters**: e.g. ?something=true&name=tom
* **A Method**: e.g. GET
* **Request headers**: e.g. Accept: application/json
The following sections will present an overview over how that request is being processed to provide an in depth view over how Nextcloud works. If you are not interested in the internals or don’t want to execute anything before and after your controller, feel free to skip this section and continue directly with defining [your app’s routes](https://docs.nextcloud.com/server/latest/developer_manual/basics/routing.html)
.
Front controller[](https://docs.nextcloud.com/server/latest/developer_manual/basics/request_lifecycle.html#front-controller "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------
In the beginning, all requests are sent to Nextcloud’s `index.php` which in turn executes `lib/base.php`. This file inspects the HTTP headers, abstracts away differences between different Web servers and initializes the basic classes. Afterwards the basic apps are being loaded in the following order:
* Authentication backends
* Filesystem
* Logging
The type of the app is determined by inspecting the app’s [configuration file](https://docs.nextcloud.com/server/latest/developer_manual/app_development/info.html)
(`appinfo/info.xml`). Each installed app is being loaded and executed (see [Bootstrap](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html)
). That means that if you want to execute code before a specific app is being run, you can place code in your app’s [Navigation and pre-app configuration](https://docs.nextcloud.com/server/latest/developer_manual/app_development/init.html)
file.
Afterwards the following steps are performed:
* Try to authenticate the user
* Load and execute all the remaining apps’ [Navigation and pre-app configuration](https://docs.nextcloud.com/server/latest/developer_manual/app_development/init.html)
files
* Load and run all the routes in the apps’ `appinfo/routes.php`
* Execute the router
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Events — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/latest/developer_manual/basics/index.html)
* Events
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/events.rst)
* * *
Events[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#events "Link to this heading")
======================================================================================================================
Events are used to communicate between different aspects of the Nextcloud eco system. They are used in the Nextcloud server internally, for server-to-apps communication as well as inter-app communication.
Overview[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#overview "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------
The term “events” is a bit broad in Nextcloud and there are multiple ways of emitting them.
* [OCP event dispatcher](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-event-dispatcher)
* [Hooks](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#hooks)
* [Public Emitter](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#public-emitter)
OCP event dispatcher[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-event-dispatcher "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
This mechanism is a versatile and typed approach to events in Nextcloud’s php code. It uses objects rather than just passing primitives or untyped arrays. This should help provide a better developer experience while lowering the risk of unexpected changes in the API that are hard to find after the initial implementation.
### Naming scheme[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#naming-scheme "Link to this heading")
The name should reflect the subject and the actions. Suffixing event classes with Event makes it easier to recognize their purpose.
For example, if a user is created, a UserCreatedEvent will be emitted.
Events are usually emitted _after_ the event has happened. If it’s emitted before, it should be prefixed with Before.
Thus BeforeUserCreatedEvent is emitted _before_ the user data is written to the database.
Note
Although you may choose to name your event classes differently, sticking to the convention will allow Nextcloud developers understand each other’s apps more easily.
Note
For backwards compatibility with the Symfony class [GenericEvent](https://symfony.com/doc/current/components/event_dispatcher/generic_event.html)
, Nextcloud also provides a `\OCP\EventDispatcher\Event` class. With the release of Nextcloud 22 this class has been deprecated. Named and typed event classes should be used instead.
### Writing events[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#writing-events "Link to this heading")
As a rule events are dedicated classes extending `\OCP\EventDispatcher\Event`.
user \= $user;
}
public function getUser(): IUser {
return $this\->user;
}
}
### Writing a listener[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#writing-a-listener "Link to this heading")
A listener can be a simple callback function (or anything else that is [callable](https://www.php.net/manual/en/language.types.callable.php)
, or a dedicated class.
#### Listener callbacks[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#listener-callbacks "Link to this heading")
You can use simple callback to react on events. They will receive the event object as first and only parameter. You can type-hint the base Event class or the subclass you expect and register for.
getContainer()\->query(IEventDispatcher::class);
$dispatcher\->addListener(AddEvent::class, function(AddEvent $event) {
// ...
});
}
}
Note
Type-hinting the actual event class will give you better IDE and static analyzers support. It’s generally safe to assume the dispatcher will not give you any other objects.
#### Listener classes[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#listener-classes "Link to this heading")
A class that can handle an event will implement the `\OCP\EventDispatcher\IEventListener` interface. Class names should end with Listener.
addToCounter(2);
}
}
Note
Php parameter type hints are not allowed to be more specific than the type hints on the interface, thus you can’t use AddEvent in the method signature but use an instanceOf instead.
In the `Application.php` the event and the listener class are connected. The class is instantiated only when the actual event is fired.
getContainer()\->get(IEventDispatcher::class);
$dispatcher\->addServiceListener(AddEvent::class, AddTwoListener::class);
}
}
Note
The listener is resolved via the DI container, therefore you can add a constructor and type-hint services required for processing the event.
### Available Events[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#available-events "Link to this heading")
Here you find an overview of the public events that can be consumed in apps. See their source files for more details.
#### `\OCA\DAV\Events\AddressBookCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-addressbookcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new address-book.
#### `\OCA\DAV\Events\AddressBookDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-addressbookdeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes an address-book.
#### `\OCA\DAV\Events\AddressBookShareUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-addressbookshareupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user shares or unshares an address-book.
#### `\OCA\DAV\Events\AddressBookUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-addressbookupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates an address-book.
#### `\OCA\DAV\Events\CachedCalendarObjectCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-cachedcalendarobjectcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a cached calendar object is being created while fetching a calendar-subscription.
#### `\OCA\DAV\Events\CachedCalendarObjectDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-cachedcalendarobjectdeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a cached calendar object is being deleted while fetching a calendar-subscription.
#### `\OCA\DAV\Events\CachedCalendarObjectUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-cachedcalendarobjectupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a cached calendar object is being updated while fetching a calendar-subscription.
#### `\OCA\DAV\Events\CalendarCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new calendar.
#### `\OCA\DAV\Events\CalendarDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendardeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar.
#### `\OCA\DAV\Events\CalendarObjectCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarobjectcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a calendar-object.
#### `\OCA\DAV\Events\CalendarObjectDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarobjectdeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar-object.
#### `\OCA\DAV\Events\CalendarObjectUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarobjectupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates a calendar-object.
#### `\OCA\DAV\Events\CalendarPublishedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarpublishedevent "Link to this heading")
Added in version 20.
This event is triggered when a user publishes a calendar.
#### `\OCA\DAV\Events\CalendarShareUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarshareupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user shares or unshares a calendar.
#### `\OCA\DAV\Events\CalendarUnpublishedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarunpublishedevent "Link to this heading")
Added in version 20.
This event is triggered when a user unpublishes calendar.
#### `\OCA\DAV\Events\CalendarUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-calendarupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates a calendar.
#### `\OCA\DAV\Events\CardCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-cardcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new card in an address-book.
#### `\OCA\DAV\Events\CardDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-carddeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a card in an address-book.
#### `\OCA\DAV\Events\CardUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-cardupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates a card in an address-book.
#### `OCA\DAV\Events\SabrePluginAddEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-sabrepluginaddevent "Link to this heading")
Added in version 28.
This event is triggered during the setup of the SabreDAV server to allow the registration of additional plugins.
#### `\OCA\DAV\Events\SabrePluginAuthInitEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-sabrepluginauthinitevent "Link to this heading")
Added in version 20.
This event is triggered during the setup of the SabreDAV server to allow the registration of additional authentication backends.
#### `\OCA\DAV\Events\SubscriptionCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-subscriptioncreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new calendar-subscription.
#### `\OCA\DAV\Events\SubscriptionDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-subscriptiondeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar-subscription.
#### `\OCA\DAV\Events\SubscriptionUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-dav-events-subscriptionupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar-subscription.
#### `\OCA\FederatedFileSharing\Events\FederatedShareAddedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-federatedfilesharing-events-federatedshareaddedevent "Link to this heading")
Added in version 20.
This event is triggered when a federated share is successfully added.
#### `\OCA\Files\Event\LoadAdditionalScriptsEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-files-event-loadadditionalscriptsevent "Link to this heading")
Added in version 17.
This event is triggered when the files app is rendered. It can be used to add additional scripts to the files app.
#### `\OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-files-sharing-event-beforetemplaterenderedevent "Link to this heading")
Added in version 20.
Emitted before the rendering step of the public share page happens. The event holds a flag that specifies if it is the authentication page of a public share.
#### `\OCA\Files_Trashbin\Events\MoveToTrashEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-files-trashbin-events-movetotrashevent "Link to this heading")
Added in version 28.
Emitted after a file or folder is moved to the trashbin.
#### `\OCA\Settings\Events\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-settings-events-beforetemplaterenderedevent "Link to this heading")
Added in version 20.
This event is triggered right before the user management template is rendered.
#### `\OCA\User_LDAP\Events\GroupBackendRegistered`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-user-ldap-events-groupbackendregistered "Link to this heading")
Added in version 20.
This event is triggered right after the LDAP group backend is registered.
#### `\OCA\User_LDAP\Events\UserBackendRegistered`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-user-ldap-events-userbackendregistered "Link to this heading")
Added in version 20.
This event is triggered right after the LDAP user backend is registered.
#### `\OCA\Viewer\Event\LoadViewer`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#oca-viewer-event-loadviewer "Link to this heading")
Added in version 17.
This event is triggered whenever the viewer is loaded and extensions should be loaded.
#### `OCP\Accounts\UserUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-accounts-userupdatedevent "Link to this heading")
Added in version 28.
This event is triggered when the account data of a user was updated.
#### `OCP\App\Events\AppDisableEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-app-events-appdisableevent "Link to this heading")
Added in version 27.
This event is triggered when an app is disabled.
#### `OCP\App\Events\AppEnableEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-app-events-appenableevent "Link to this heading")
Added in version 27.
This event is triggered when an app is enabled.
#### `OCP\App\Events\AppUpdateEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-app-events-appupdateevent "Link to this heading")
Added in version 27.
This event is triggered when an app is updated.
#### `OCP\App\ManagerEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-app-managerevent "Link to this heading")
Added in version 9.
Class ManagerEvent
#### `OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-appframework-http-events-beforelogintemplaterenderedevent "Link to this heading")
Added in version 28.
Emitted before the rendering step of the login TemplateResponse.
#### `OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-appframework-http-events-beforetemplaterenderedevent "Link to this heading")
Added in version 20.
Emitted before the rendering step of each TemplateResponse. The event holds a flag that specifies if an user is logged in.
#### `OCP\Authentication\Events\AnyLoginFailedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-events-anyloginfailedevent "Link to this heading")
Added in version 26.
Emitted when the authentication fails
#### `OCP\Authentication\Events\LoginFailedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-events-loginfailedevent "Link to this heading")
Added in version 19.
Emitted when the authentication fails, but only if the login name can be associated with an existing user.
#### `OCP\Authentication\Events\TokenInvalidatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-events-tokeninvalidatedevent "Link to this heading")
Added in version 32.
Emitted when an authentication token is invalidated.
#### `OCP\Authentication\TwoFactorAuth\RegistryEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-registryevent "Link to this heading")
Added in version 15.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengeFailed`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderchallengefailed "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengePassed`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderchallengepassed "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderDisabled`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderdisabled "Link to this heading")
Added in version 20.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserDisabled`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserdisabled "Link to this heading")
Added in version 22.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserEnabled`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserenabled "Link to this heading")
Added in version 22.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserRegistered`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserregistered "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserUnregistered`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserunregistered "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderUserDeleted`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorprovideruserdeleted "Link to this heading")
Added in version 28.
#### `OCP\BeforeSabrePubliclyLoadedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-beforesabrepubliclyloadedevent "Link to this heading")
Added in version 26.
Dispatched before Sabre is loaded when accessing public webdav endpoints This can be used to inject a Sabre plugin for example
#### `OCP\Calendar\Events\CalendarObjectCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-calendar-events-calendarobjectcreatedevent "Link to this heading")
Added in version 32.
#### `OCP\Calendar\Events\CalendarObjectDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-calendar-events-calendarobjectdeletedevent "Link to this heading")
Added in version 32.
#### `OCP\Calendar\Events\CalendarObjectMovedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-calendar-events-calendarobjectmovedevent "Link to this heading")
Added in version 32.
#### `OCP\Calendar\Events\CalendarObjectMovedToTrashEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-calendar-events-calendarobjectmovedtotrashevent "Link to this heading")
Added in version 32.
#### `OCP\Calendar\Events\CalendarObjectRestoredEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-calendar-events-calendarobjectrestoredevent "Link to this heading")
Added in version 32.
#### `OCP\Calendar\Events\CalendarObjectUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-calendar-events-calendarobjectupdatedevent "Link to this heading")
Added in version 32.
#### `OCP\Collaboration\AutoComplete\AutoCompleteEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-collaboration-autocomplete-autocompleteevent "Link to this heading")
Added in version 16.
#### `OCP\Collaboration\AutoComplete\AutoCompleteFilterEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-collaboration-autocomplete-autocompletefilterevent "Link to this heading")
Added in version 28.
#### `OCP\Collaboration\Reference\RenderReferenceEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-collaboration-reference-renderreferenceevent "Link to this heading")
Added in version 25.
Event emitted when apps might render references like link previews or smart picker widgets. This can be used to inject scripts for extending that. Further details can be found in the [Reference providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#reference-providers)
deep dive.
#### `OCP\Collaboration\Resources\LoadAdditionalScriptsEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-collaboration-resources-loadadditionalscriptsevent "Link to this heading")
Added in version 25.
This event is used by apps to register their own frontend scripts for integrating projects in their app. Apps also need to dispatch the event in order to load scripts during page load
#### `OCP\Comments\CommentsEntityEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-comments-commentsentityevent "Link to this heading")
Added in version 9.1.
Changed in version 28.0.0: Dispatched as a typed event
Class CommentsEntityEvent
#### `OCP\Comments\CommentsEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-comments-commentsevent "Link to this heading")
Added in version 9.
Class CommentsEvent
#### `OCP\Config\BeforePreferenceDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-config-beforepreferencedeletedevent "Link to this heading")
Added in version 25.
#### `OCP\Config\BeforePreferenceSetEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-config-beforepreferencesetevent "Link to this heading")
Added in version 25.
#### `OCP\Console\ConsoleEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-console-consoleevent "Link to this heading")
Added in version 9.
Class ConsoleEvent
#### `OCP\Contacts\Events\ContactInteractedWithEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-contacts-events-contactinteractedwithevent "Link to this heading")
Added in version 19.
An event that allows apps to notify other components about an interaction between two users. This can be used to build better recommendations and suggestions in user interfaces. Emitters should add at least one identifier (uid, email, federated cloud ID) of the recipient of the interaction.
#### `OCP\DB\Events\AddMissingColumnsEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-db-events-addmissingcolumnsevent "Link to this heading")
Added in version 28.
Event to allow apps to register information about missing database columns This event will be dispatched for checking on the admin settings and when running occ db:add-missing-columns which will then create those columns
#### `OCP\DB\Events\AddMissingIndicesEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-db-events-addmissingindicesevent "Link to this heading")
Added in version 28.
Event to allow apps to register information about missing database indices This event will be dispatched for checking on the admin settings and when running occ db:add-missing-indices which will then create those indices
#### `OCP\DB\Events\AddMissingPrimaryKeyEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-db-events-addmissingprimarykeyevent "Link to this heading")
Added in version 28.
Event to allow apps to register information about missing database primary keys This event will be dispatched for checking on the admin settings and when running occ db:add-missing-primary-keys which will then create those keys
#### `OCP\DirectEditing\RegisterDirectEditorEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-directediting-registerdirecteditorevent "Link to this heading")
Added in version 18.
Event to allow to register the direct editor.
#### `OCP\EventDispatcher\GenericEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-eventdispatcher-genericevent "Link to this heading")
Added in version 18.
Class GenericEvent convenience re-implementation of SymfonyComponentGenericEvent against OCPEventDispatcherEvent
#### `OCP\Federation\Events\TrustedServerRemovedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-federation-events-trustedserverremovedevent "Link to this heading")
Added in version 25.
#### `OCP\Files\Cache\AbstractCacheEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-cache-abstractcacheevent "Link to this heading")
Added in version 22.
#### `OCP\Files\Cache\CacheEntryInsertedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-cache-cacheentryinsertedevent "Link to this heading")
Added in version 21.
Event for when an existing entry in the cache gets inserted
#### `OCP\Files\Cache\CacheEntryRemovedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-cache-cacheentryremovedevent "Link to this heading")
Added in version 21.
Event for when an existing entry in the cache gets removed
#### `OCP\Files\Cache\CacheEntryUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-cache-cacheentryupdatedevent "Link to this heading")
Added in version 21.
Event for when an existing entry in the cache gets updated
#### `OCP\Files\Cache\CacheInsertEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-cache-cacheinsertevent "Link to this heading")
Added in version 16.
Event for when a new entry gets added to the cache
#### `OCP\Files\Cache\CacheUpdateEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-cache-cacheupdateevent "Link to this heading")
Added in version 16.
Event for when an existing entry in the cache gets updated
#### `OCP\Files\Config\Event\UserMountAddedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-config-event-usermountaddedevent "Link to this heading")
Added in version 31.
Event emitted when a user mount was added.
#### `OCP\Files\Config\Event\UserMountRemovedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-config-event-usermountremovedevent "Link to this heading")
Added in version 31.
Event emitted when a user mount was removed.
#### `OCP\Files\Config\Event\UserMountUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-config-event-usermountupdatedevent "Link to this heading")
Added in version 31.
Event emitted when a user mount was moved.
#### `OCP\Files\Events\BeforeDirectFileDownloadEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-beforedirectfiledownloadevent "Link to this heading")
Added in version 25.
This event is triggered when a user tries to download a file directly.
#### `OCP\Files\Events\BeforeFileScannedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-beforefilescannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\BeforeFileSystemSetupEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-beforefilesystemsetupevent "Link to this heading")
Added in version 31.
Event triggered before the file system is setup
#### `OCP\Files\Events\BeforeFolderScannedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-beforefolderscannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\BeforeZipCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-beforezipcreatedevent "Link to this heading")
Added in version 25.
This event is triggered before a archive is created when a user requested downloading a folder or multiple files. By setting successful to false the tar creation can be aborted and the download denied.
#### `OCP\Files\Events\FileCacheUpdated`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-filecacheupdated "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\FileScannedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-filescannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\FolderScannedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-folderscannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\InvalidateMountCacheEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-invalidatemountcacheevent "Link to this heading")
Added in version 24.
Used to notify the filesystem setup manager that the available mounts for a user have changed
#### `OCP\Files\Events\Node\BeforeNodeCopiedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-beforenodecopiedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-beforenodecreatedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-beforenodedeletedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeReadEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-beforenodereadevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeRenamedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-beforenoderenamedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeTouchedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-beforenodetouchedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeWrittenEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-beforenodewrittenevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\FilesystemTornDownEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-filesystemtorndownevent "Link to this heading")
Added in version 24.
Event fired after the filesystem has been torn down
#### `OCP\Files\Events\Node\NodeCopiedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-nodecopiedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-nodecreatedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-nodedeletedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeRenamedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-noderenamedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeTouchedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-nodetouchedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeWrittenEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-node-nodewrittenevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\NodeAddedToCache`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-nodeaddedtocache "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\NodeAddedToFavorite`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-nodeaddedtofavorite "Link to this heading")
Added in version 28.
#### `OCP\Files\Events\NodeRemovedFromCache`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-noderemovedfromcache "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\NodeRemovedFromFavorite`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-events-noderemovedfromfavorite "Link to this heading")
Added in version 28.
#### `OCP\Files\ObjectStore\Events\BucketCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-objectstore-events-bucketcreatedevent "Link to this heading")
Added in version 33.
#### `OCP\Files\Template\BeforeGetTemplatesEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-template-beforegettemplatesevent "Link to this heading")
Added in version 30.
#### `OCP\Files\Template\FileCreatedFromTemplateEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-template-filecreatedfromtemplateevent "Link to this heading")
Added in version 21.
#### `OCP\Files\Template\RegisterTemplateCreatorEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-files-template-registertemplatecreatorevent "Link to this heading")
Added in version 30.
#### `OCP\FilesMetadata\Event\MetadataBackgroundEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-filesmetadata-event-metadatabackgroundevent "Link to this heading")
Added in version 28.
MetadataBackgroundEvent is an event similar to MetadataLiveEvent but dispatched on a background thread instead of live thread. Meaning there is no limit to the time required for the generation of your metadata.
#### `OCP\FilesMetadata\Event\MetadataLiveEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-filesmetadata-event-metadataliveevent "Link to this heading")
Added in version 28.
MetadataLiveEvent is an event initiated when a file is created or updated. The app contains the Node related to the created/updated file, and a FilesMetadata that already contains the currently known metadata.
Setting new metadata, or modifying already existing metadata with different value, will trigger the save of the metadata in the database.
#### `OCP\FilesMetadata\Event\MetadataNamedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-filesmetadata-event-metadatanamedevent "Link to this heading")
Added in version 28.
MetadataNamedEvent is an event similar to MetadataBackgroundEvent completed with a target name, used to limit the refresh of metadata only listeners capable of filtering themselves out. Meaning that when using this event, your app must implement a filter on the event’s registered name returned by getName()
This event is mostly triggered when a registered name is added to the files scan
i.e. ./occ files:scan –generate-metadata \[name\]
#### `OCP\Group\Events\BeforeGroupChangedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-beforegroupchangedevent "Link to this heading")
Added in version 26.
#### `OCP\Group\Events\BeforeGroupCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-beforegroupcreatedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\BeforeGroupDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-beforegroupdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\BeforeUserAddedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-beforeuseraddedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\BeforeUserRemovedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-beforeuserremovedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\GroupChangedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-groupchangedevent "Link to this heading")
Added in version 26.
#### `OCP\Group\Events\GroupCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-groupcreatedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\GroupDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-groupdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\SubAdminAddedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-subadminaddedevent "Link to this heading")
Added in version 21.
#### `OCP\Group\Events\SubAdminRemovedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-subadminremovedevent "Link to this heading")
Added in version 21.
#### `OCP\Group\Events\UserAddedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-useraddedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\UserRemovedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-group-events-userremovedevent "Link to this heading")
Added in version 18.
#### `OCP\Log\Audit\CriticalActionPerformedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-log-audit-criticalactionperformedevent "Link to this heading")
Added in version 22.
Emitted when the admin\_audit app should log an entry
#### `OCP\Log\BeforeMessageLoggedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-log-beforemessageloggedevent "Link to this heading")
Added in version 28.
Even for when a log item is being logged
#### `OCP\Mail\Events\BeforeMessageSent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-mail-events-beforemessagesent "Link to this heading")
Added in version 19.
Emitted before a system mail is sent. It can be used to alter the message.
#### `OCP\Navigation\Events\LoadAdditionalEntriesEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-navigation-events-loadadditionalentriesevent "Link to this heading")
Added in version 31.
#### `OCP\OCM\Events\ResourceTypeRegisterEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-ocm-events-resourcetyperegisterevent "Link to this heading")
Added in version 28.
Use this event to register additional OCM resources before the API returns them in the OCM provider list and capability
#### `OCP\Preview\BeforePreviewFetchedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-preview-beforepreviewfetchedevent "Link to this heading")
Added in version 25.0.1.
Changed in version 28.0.0: the constructor arguments `$width`, `$height`, `$crop` and `$mode` are no longer nullable.
Changed in version 31.0.0: the constructor arguments `$mimeType` was added
Emitted before a file preview is being fetched. It can be used to block preview rendering by throwing a `OCP\Files\NotFoundException`
#### `OCP\Profile\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-profile-beforetemplaterenderedevent "Link to this heading")
Added in version 25.
Emitted before the rendering step of the public profile page happens.
#### `OCP\SabrePluginEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-sabrepluginevent "Link to this heading")
Added in version 8.2.
#### `OCP\Security\CSP\AddContentSecurityPolicyEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-security-csp-addcontentsecuritypolicyevent "Link to this heading")
Added in version 17.
Allows to inject something into the default content policy. This is for example useful when you’re injecting Javascript code into a view belonging to another controller and cannot modify its Content-Security-Policy itself. Note that the adjustment is only applied to applications that use AppFramework controllers.
WARNING: Using this API incorrectly may make the instance more insecure. Do think twice before adding whitelisting resources. Please do also note that it is not possible to use the disallowXYZ functions.
#### `OCP\Security\Events\GenerateSecurePasswordEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-security-events-generatesecurepasswordevent "Link to this heading")
Added in version 18.
Event to request a secure password to be generated.
Since Nextcloud 31 this event also provides a `getContext` method allowing to apply different rules for different password context like account passwords or share passwords.
#### `OCP\Security\Events\ValidatePasswordPolicyEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-security-events-validatepasswordpolicyevent "Link to this heading")
Added in version 18.
This event can be emitted to request a validation of a password. If a password policy app is installed and the password is invalid, an OCPHintException will be thrown.
Since Nextcloud 31 this event also provides a `getContext` method allowing to apply different rules for different password context like account passwords or share passwords.
#### `OCP\Security\FeaturePolicy\AddFeaturePolicyEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-security-featurepolicy-addfeaturepolicyevent "Link to this heading")
Added in version 17.
Event that allows to register a feature policy header to a request.
#### `OCP\Settings\Events\DeclarativeSettingsGetValueEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-settings-events-declarativesettingsgetvalueevent "Link to this heading")
Added in version 29.
#### `OCP\Settings\Events\DeclarativeSettingsRegisterFormEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-settings-events-declarativesettingsregisterformevent "Link to this heading")
Added in version 29.
#### `OCP\Settings\Events\DeclarativeSettingsSetValueEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-settings-events-declarativesettingssetvalueevent "Link to this heading")
Added in version 29.
#### `OCP\Share\Events\BeforeShareCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-share-events-beforesharecreatedevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\BeforeShareDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-share-events-beforesharedeletedevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\ShareAcceptedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-share-events-shareacceptedevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\ShareCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-share-events-sharecreatedevent "Link to this heading")
Added in version 18.
#### `OCP\Share\Events\ShareDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-share-events-sharedeletedevent "Link to this heading")
Added in version 21.
#### `OCP\Share\Events\ShareDeletedFromSelfEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-share-events-sharedeletedfromselfevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\VerifyMountPointEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-share-events-verifymountpointevent "Link to this heading")
Added in version 19.
#### `OCP\SpeechToText\Events\TranscriptionFailedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-speechtotext-events-transcriptionfailedevent "Link to this heading")
Added in version 27.
This Event is emitted if a transcription of a media file using a Speech-To-Text provider failed
#### `OCP\SpeechToText\Events\TranscriptionSuccessfulEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-speechtotext-events-transcriptionsuccessfulevent "Link to this heading")
Added in version 27.
This Event is emitted when a transcription of a media file happened successfully
#### `OCP\SystemTag\ManagerEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-systemtag-managerevent "Link to this heading")
Added in version 9.
Class ManagerEvent
#### `OCP\SystemTag\MapperEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-systemtag-mapperevent "Link to this heading")
Added in version 9.
Class MapperEvent
#### `OCP\SystemTag\SystemTagsEntityEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-systemtag-systemtagsentityevent "Link to this heading")
Added in version 9.1.
Changed in version 28.0.0: Dispatched as a typed event
Class SystemTagsEntityEvent
#### `OCP\TaskProcessing\Events\GetTaskProcessingProvidersEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-taskprocessing-events-gettaskprocessingprovidersevent "Link to this heading")
Added in version 32.
Event dispatched by the server to collect Task Processing Providers and custom Task Types from listeners (like AppAPI). Listeners should add their providers and task types using the addProvider() and addTaskType() methods.
#### `OCP\TaskProcessing\Events\TaskFailedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-taskprocessing-events-taskfailedevent "Link to this heading")
Added in version 30.
#### `OCP\TaskProcessing\Events\TaskSuccessfulEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-taskprocessing-events-tasksuccessfulevent "Link to this heading")
Added in version 30.
#### `OCP\TextProcessing\Events\TaskFailedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-textprocessing-events-taskfailedevent "Link to this heading")
Added in version 27.1.
#### `OCP\TextProcessing\Events\TaskSuccessfulEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-textprocessing-events-tasksuccessfulevent "Link to this heading")
Added in version 27.1.
#### `OCP\TextToImage\Events\TaskFailedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-texttoimage-events-taskfailedevent "Link to this heading")
Added in version 28.
#### `OCP\TextToImage\Events\TaskSuccessfulEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-texttoimage-events-tasksuccessfulevent "Link to this heading")
Added in version 28.
#### `OCP\User\Events\BeforePasswordUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-beforepasswordupdatedevent "Link to this heading")
Added in version 18.
Emitted before the user password is updated.
#### `OCP\User\Events\BeforeUserCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-beforeusercreatedevent "Link to this heading")
Added in version 18.
Emitted before a new user is created on the back-end.
#### `OCP\User\Events\BeforeUserDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-beforeuserdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\BeforeUserIdUnassignedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-beforeuseridunassignedevent "Link to this heading")
Added in version 31.
Emitted before removing the mapping between an external user and an internal userid
#### `OCP\User\Events\BeforeUserLoggedInEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-beforeuserloggedinevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\BeforeUserLoggedInWithCookieEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-beforeuserloggedinwithcookieevent "Link to this heading")
Added in version 18.
Emitted before a user is logged in via remember-me cookies.
#### `OCP\User\Events\BeforeUserLoggedOutEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-beforeuserloggedoutevent "Link to this heading")
Added in version 18.
Emitted before a user is logged out.
#### `OCP\User\Events\OutOfOfficeChangedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-outofofficechangedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period has changed
#### `OCP\User\Events\OutOfOfficeClearedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-outofofficeclearedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period is cleared
#### `OCP\User\Events\OutOfOfficeEndedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-outofofficeendedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period ended
#### `OCP\User\Events\OutOfOfficeScheduledEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-outofofficescheduledevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period is scheduled
#### `OCP\User\Events\OutOfOfficeStartedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-outofofficestartedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period started
#### `OCP\User\Events\PasswordUpdatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-passwordupdatedevent "Link to this heading")
Added in version 18.
Emitted when the user password has been updated.
#### `OCP\User\Events\PostLoginEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-postloginevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserChangedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-userchangedevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserCreatedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-usercreatedevent "Link to this heading")
Added in version 18.
Emitted when a new user has been created on the back-end.
#### `OCP\User\Events\UserDeletedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-userdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserFirstTimeLoggedInEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-userfirsttimeloggedinevent "Link to this heading")
Added in version 28.
#### `OCP\User\Events\UserIdAssignedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-useridassignedevent "Link to this heading")
Added in version 31.
Emitted by backends (like user\_ldap) when a user created externally is mapped for the first time and assigned a userid
#### `OCP\User\Events\UserIdUnassignedEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-useridunassignedevent "Link to this heading")
Added in version 31.
Emitted after removing the mapping between an external user and an internal userid
#### `OCP\User\Events\UserLiveStatusEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-userlivestatusevent "Link to this heading")
Added in version 20.
#### `OCP\User\Events\UserLoggedInEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-userloggedinevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserLoggedInWithCookieEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-userloggedinwithcookieevent "Link to this heading")
Added in version 18.
Emitted when a user has been successfully logged in via remember-me cookies.
#### `OCP\User\Events\UserLoggedOutEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-events-userloggedoutevent "Link to this heading")
Added in version 18.
Emitted when a user has been logged out successfully.
#### `OCP\User\GetQuotaEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-user-getquotaevent "Link to this heading")
Added in version 20.
Event to allow apps to
#### `OCP\WorkflowEngine\Events\LoadSettingsScriptsEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-workflowengine-events-loadsettingsscriptsevent "Link to this heading")
Added in version 20.
Emitted when the workflow engine settings page is loaded.
#### `OCP\WorkflowEngine\Events\RegisterChecksEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-workflowengine-events-registerchecksevent "Link to this heading")
Added in version 18.
#### `OCP\WorkflowEngine\Events\RegisterEntitiesEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-workflowengine-events-registerentitiesevent "Link to this heading")
Added in version 18.
#### `OCP\WorkflowEngine\Events\RegisterOperationsEvent`[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-workflowengine-events-registeroperationsevent "Link to this heading")
Added in version 18.
Hooks[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#hooks "Link to this heading")
--------------------------------------------------------------------------------------------------------------------
Deprecated since version 18: Use the [OCP event dispatcher](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-event-dispatcher)
instead.
Hooks are used to execute code before or after an event has occurred. This is for instance useful to run cleanup code after users, groups or files have been deleted. Hooks should be registered in the [Bootstrapping process](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html)
.
### Available hooks[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#available-hooks "Link to this heading")
The scope is the first parameter that is passed to the **listen** method, the second parameter is the method and the third one the callback that should be executed once the hook is being called, e.g.:
listen('\\OC\\User', 'preDelete', $callback);
Hooks can also be removed by using the **removeListener** method on the object:
removeListener(null, null, $callback);
The following hooks are available:
### Session[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#session "Link to this heading")
Injectable from the ServerContainer with the `\OCP\IUserSession` service.
Hooks available in scope **\\OC\\User**:
* **preSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **postSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **changeUser** (\\OC\\User\\User $user, string $feature, string $value)
* **preDelete** (\\OC\\User\\User $user)
* **postDelete** (\\OC\\User\\User $user)
* **preCreateUser** (string $uid, string $password)
* **postCreateUser** (\\OC\\User\\User $user)
* **preLogin** (string $user, string $password)
* **postLogin** (\\OC\\User\\User $user, string $password)
* **logout** ()
### UserManager[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#usermanager "Link to this heading")
Injectable from the ServerContainer with the `\OCP\IUserManager` service.
Hooks available in scope **\\OC\\User**:
* **preSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **postSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **preDelete** (\\OC\\User\\User $user)
* **postDelete** (\\OC\\User\\User $user)
* **preCreateUser** (string $uid, string $password)
* **postCreateUser** (\\OC\\User\\User $user, string $password)
### GroupManager[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#groupmanager "Link to this heading")
Hooks available in scope **\\OC\\Group**:
* **preAddUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **postAddUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **preRemoveUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **postRemoveUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **preDelete** (\\OC\\Group\\Group $group)
* **postDelete** (\\OC\\Group\\Group $group)
* **preCreate** (string $groupId)
* **postCreate** (\\OC\\Group\\Group $group)
### Filesystem root[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#filesystem-root "Link to this heading")
Injectable from the ServerContainer by calling the method **getRootFolder()**, **getUserFolder()** or **getAppFolder()**.
To enable these events for your app you should add the following to your info.xml file:
Filesystem hooks available in scope **\\OC\\Files**:
* **preWrite** (\\OCP\\Files\\Node $node)
* **postWrite** (\\OCP\\Files\\Node $node)
* **preCreate** (\\OCP\\Files\\Node $node)
* **postCreate** (\\OCP\\Files\\Node $node)
* **preDelete** (\\OCP\\Files\\Node $node)
* **postDelete** (\\OCP\\Files\\Node $node)
* **preTouch** (\\OCP\\Files\\Node $node, int $mtime)
* **postTouch** (\\OCP\\Files\\Node $node)
* **preCopy** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
* **postCopy** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
* **preRename** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
* **postRename** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
### Filesystem scanner[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#filesystem-scanner "Link to this heading")
Filesystem scanner hooks available in scope **\\OC\\Files\\Utils\\Scanner**:
* **scanFile** (string $absolutePath)
* **scanFolder** (string $absolutePath)
* **postScanFile** (string $absolutePath)
* **postScanFolder** (string $absolutePath)
Public emitter[](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#public-emitter "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------
Deprecated since version 18: Use the [OCP event dispatcher](https://docs.nextcloud.com/server/latest/developer_manual/basics/events.html#ocp-event-dispatcher)
instead.
tbd
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Controllers — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/latest/developer_manual/basics/index.html)
* Controllers
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/controllers.rst)
* * *
Controllers[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#controllers "Link to this heading")
=====================================================================================================================================
Controllers are used to connect [routes](https://docs.nextcloud.com/server/latest/developer_manual/basics/routing.html)
with app logic. Think of it as callbacks that are executed once a request has come in. Controllers are defined inside the **lib/Controller/** directory.
To create a controller, simply extend the Controller class and create a method that should be executed on a request:
$id = 3
// $doMore = false
// $value = 3.5
}
}
The following types will be cast:
* **bool** or **boolean**
* **float**
* **int** or **integer**
### JSON parameters[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#json-parameters "Link to this heading")
It is possible to pass JSON using a POST, PUT or PATCH request. To do that the **Content-Type** header has to be set to **application/json**. The JSON is being parsed as an array and the first level keys will be used to pass in the arguments, e.g.:
POST /index.php/apps/myapp/authors
Content\-Type: application/json
{
"name": "test",
"number": 3,
"publisher": true,
"customFields": {
"mail": "test@example.com",
"address": "Somewhere"
}
}
"test@example.com", "address" => "Somewhere")
}
}
### Reading headers, files, cookies and environment variables[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#reading-headers-files-cookies-and-environment-variables "Link to this heading")
Headers, files, cookies and environment variables can be accessed directly from the request object:
request\->getHeader('Content-Type'); // $\_SERVER\['HTTP\_CONTENT\_TYPE'\]
$cookie \= $this\->request\->getCookie('myCookie'); // $\_COOKIES\['myCookie'\]
$file \= $this\->request\->getUploadedFile('myfile'); // $\_FILES\['myfile'\]
$env \= $this\->request\->getEnv('SOME\_VAR'); // $\_ENV\['SOME\_VAR'\]
}
}
Why should those values be accessed from the request object and not from the global array like $\_FILES? Simple: [because it’s bad practice](http://c2.com/cgi/wiki?GlobalVariablesAreBad)
and will make testing harder.
### Reading and writing session variables[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#reading-and-writing-session-variables "Link to this heading")
To set, get or modify session variables, the ISession object has to be injected into the controller.
Nextcloud will read existing session data at the beginning of the request lifecycle and close the session afterwards. This means that in order to write to the session, the session has to be opened first. This is done implicitly when calling the set method, but would close immediately afterwards. To prevent this, the session has to be explicitly opened by calling the reopen method.
Alternatively, you can use the `#[UseSession]` attribute to automatically open and close the session for you.
use OCP\\AppFramework\\Controller;
use OCP\\AppFramework\\Http\\Attribute\\UseSession;
use OCP\\AppFramework\\Http\\Response;
class PageController extends Controller {
#\[UseSession\] public function writeASessionVariable(): Response {
// ...
}
}
Note
The `#[UseSession]` was added in Nextcloud 26 and requires PHP 8.0 or later. If your app targets older releases and PHP 7.x then use the deprecated `@UseSession` annotation.
/\*\*
\* @UseSession \*/
public function writeASessionVariable(): Response {
// ....
}
In case the session may be read and written by concurrent requests of your application, keeping the session open during your controller method execution may be required to ensure that the session is locked and no other request can write to the session at the same time. When reopening the session, the session data will also get updated with the latest changes from other requests. Using the annotation will keep the session lock for the whole duration of the controller method execution.
For additional information on how session locking works in PHP see the article about [PHP Session Locking: How To Prevent Sessions Blocking in PHP requests](https://ma.ttias.be/php-session-locking-prevent-sessions-blocking-in-requests/)
.
Then session variables can be accessed like this:
Note
The session is closed automatically for writing, unless you add the `#[UseSession]` attribute!
session \= $session;
}
#\[UseSession\]
public function writeASessionVariable(): Response {
// read a session variable
$value \= $this\->session\['value'\];
// write a session variable
$this\->session\['value'\] \= 'new value';
}
}
### Setting cookies[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#setting-cookies "Link to this heading")
Cookies can be set or modified directly on the response class:
addCookie('foo', 'bar');
$response\->addCookie('bar', 'foo', new DateTime('2015-01-01 00:00'));
return $response;
}
/\*\*
\* Invalidates the cookie "foo"
\* Invalidates the cookie "bar" and "bazinga"
\*/
public function invalidateCookie(): TemplateResponse {
$response \= new TemplateResponse(...);
$response\->invalidateCookie('foo');
$response\->invalidateCookies(array('bar', 'bazinga'));
return $response;
}
}
Responses[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#responses "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------
Similar to how every controller receives a request object, every controller method has to return a Response. This can be in the form of a Response subclass or in the form of a value that can be handled by a registered responder.
There are different kinds of responses available, like HTML-based responses, data responses, or other. The app decides of which kind the response is, by returning an appropriate `Response` object in the corresponding controller method. The following sections give an overview over the various kinds and how to implement them.
HTML-based Responses[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#html-based-responses "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------
HTML pages are typically served using template responses. This is typically used as a starting point to load the website. This code linked by the template is by default encapsulated by the server to provide some common styling (e.g. the header row). The code then uses JavaScript to load further components (see [Frontend building in Vue](https://docs.nextcloud.com/server/latest/developer_manual/basics/front-end/js.html#applicationjs)
) and the actual data. This section only focuses on the actual HTML content, not the data to fill into the dynamic pages.
### Templates[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#templates "Link to this heading")
A [template](https://docs.nextcloud.com/server/latest/developer_manual/basics/front-end/templates.html)
can be rendered by returning a TemplateResponse. A TemplateResponse takes the following parameters:
* **appName**: tells the template engine in which app the template should be located
* **templateName**: the name of the template inside the templates/ folder without the .php extension
* **parameters**: optional array parameters that are available in the template through $\_, e.g.:
array('key' \=> 'something')
can be accessed through:
$\_\['key'\]
* **renderAs**: defaults to _user_, tells Nextcloud if it should include it in the web interface, or in case _blank_ is passed solely render the template
'hi');
return new TemplateResponse($this\->appName, $templateName, $parameters);
}
}
Showing a template is the only exception to the rule to [not disable CSRF checks](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#csrf-introduction)
: The user might type the URL directly (or use a browser bookmark or similar) to navigate to a HTML template. Therefore, usage of the `#[NoCSRFRequired]` attribute (see [below](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#controller-authentication)
) is acceptable in this context.
### Public page templates[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#public-page-templates "Link to this heading")
For public pages, that are rendered to users who are not logged in to the Nextcloud instance, a `OCP\\AppFramework\\Http\\Template\\PublicTemplateResponse` should be used, to load the correct base template. It also allows adding an optional set of actions that will be shown in the top right corner of the public page.
appName, 'main', \[\]);
$template\->setHeaderTitle('Public page');
$template\->setHeaderDetails('some details');
$template\->setHeaderActions(\[\
new SimpleMenuAction('download', 'Label 1', 'icon-css-class1', 'link-url', 0),\
new SimpleMenuAction('share', 'Label 2', 'icon-css-class2', 'link-url', 10),\
\]);
return $template;
}
}
The header title and subtitle will be rendered in the header, next to the logo. The action with the highest priority (lowest number) will be used as the primary action, others will shown in the popover menu on demand.
A `OCP\\AppFramework\\Http\\Template\\SimpleMenuAction` will be a link with an icon added to the menu. App developers can implement their own types of menu renderings by adding a custom class implementing the `OCP\\AppFramework\\Http\\Template\\IMenuAction` interface.
As the public template is also some HTML template, the same argumentation as for [regular templates](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#controller-template)
regarding the CSRF checks hold true: The usage of `#[NoCSRFRequired]` for public pages is considered acceptable for some pages: Each page that the user should be able to directly access (by typing/pastig the URL in the browser or clicking on a link in a mail) should have this attribute set. For multi-page forms in the second and later stages, this should **not** be set as the user should follow the series of pages.
Data-based responses[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#data-based-responses "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------
In contrast to the HTML template responses, the data responses return some user-data in packed form. There are different encodings thinkable like JSON, XML, or other formats. The main point is that the data is requested by the browser using JavaScript on behalf of the shown website. The user only indirectly requested the data by user interaction with the frontend.
### OCS[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#ocs "Link to this heading")
In order to simplify exchange of data between the Nextcloud backend and any client (be it the web frontend or whatever else), the OCS API has been introduced. Here, JSON and XML responders have been prepared and are installed without additional effort.
Note
The usage of OCS is closely related to the usage of [REST APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html)
. Unless you have a clear use-case, it is advised to use OCS over pure REST. A more detailed description can be found in [Relation of REST and OCS](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#ocs-vs-rest)
.
To use OCS in your API you can use the **OCP\\AppFramework\\OCSController** base class and return your data in the form of a **DataResponse** in the following way:
\[\
\[\
'name' \=> 'Share#getShares',\
'url' \=> '/api/v1/shares',\
'verb' \=> 'GET',\
\],\
\],\
\];
Now your method will be reachable via `/ocs/v2.php/apps//api/v1/shares`
Added in version 29: You can use the attribute `ApiRoute` as described in [Routing](https://docs.nextcloud.com/server/latest/developer_manual/basics/routing.html)
instead of the entry in `appinfo/routes.php` as an alternative.
### JSON[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#json "Link to this heading")
Warning
The usage of standard controller to access content data like JSON (no HTML) is considered legacy. Better use [OCS](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#ocscontroller)
for this type of requests.
Returning JSON is simple, just pass an array to a JSONResponse:
'hi');
return new JSONResponse($params);
}
}
Because returning JSON is such a common task, there’s even a shorter way to do this:
'hi');
}
}
Why does this work? Because the dispatcher sees that the controller did not return a subclass of a Response and asks the controller to turn the value into a Response. That’s where responders come in.
Deprecated since version 30: Usage of “index.php”-controllers for data transmission should be avoided. Use OCS instead.
### Handling errors[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#handling-errors "Link to this heading")
Sometimes a request should fail, for instance if an author with id 1 is requested but does not exist. In that case use an appropriate [HTTP error code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error)
to signal the client that an error occurred.
Each response subclass has access to the **setStatus** method which lets you set an HTTP status code. To return a JSONResponse signaling that the author with id 1 has not been found, use the following code:
registerResponder('xml', function($value) {
if ($value instanceof DataResponse) {
return new XMLResponse(
$value\->getData(),
$value\->getStatus(),
$value\->getHeaders()
);
} else {
return new XMLResponse($value);
}
});
return array('test' \=> 'hi');
}
}
Note
The above example would only return XML if the **format** parameter was _xml_. If you want to return an XMLResponse regardless of the format parameter, extend the Response class and return a new instance of it from the controller method instead.
Because returning values works fine in case of a success but not in case of failure that requires a custom HTTP error code, you can always wrap the value in a **DataResponse**. This works for both normal responses and error responses.
'not found!'), Http::STATUS\_NOT\_FOUND);
}
}
}
Miscellaneous responses[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#miscellaneous-responses "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Some special responses are available as well. These are discussed here.
### Redirects[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#redirects "Link to this heading")
A redirect can be achieved by returning a RedirectResponse:
addHeader('Content-Type', 'application/xml');
$this\->xml \= $xml;
}
public function render(): string {
$root \= new SimpleXMLElement('');
array\_walk\_recursive($this\->xml, array ($root, 'addChild'));
return $xml\->asXML();
}
}
### Streamed and lazily rendered responses[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#streamed-and-lazily-rendered-responses "Link to this heading")
By default all responses are rendered at once and sent as a string through middleware. In certain cases this is not a desirable behavior, for instance if you want to stream a file in order to save memory. To do that use the now available **OCP\\AppFramework\\Http\\StreamResponse** class:
index()` method should not check the CSRF token because it has not yet been sent to the client and because of that can’t work.
To turn off checks the following _Attributes_ can be added before the controller:
* `#[NoAdminRequired]`: Also users that are not admins can access the page
* `#[PublicPage]`: Everyone can access the page without having to log in
* `#[NoTwoFactorRequired]`: A user can access the page before the two-factor challenge has been passed (use this wisely and only in two-factor auth apps, e.g. to allow setup during login)
* `#[NoCSRFRequired]`: Don’t check the CSRF token (use this wisely since you might create a security hole; to understand what it does see [CSRF in the security section](https://docs.nextcloud.com/server/latest/developer_manual/prologue/security.html#cross-site-request-forgery)
)
Note
The attributes are only available in Nextcloud 27 or later. In older versions annotations with the same names exist:
* `@NoAdminRequired` instead of `#[NoAdminRequired]`
* `` @PublicPage` `` instead of `#[PublicPage]`
* `` @NoTwoFactorRequired` `` instead of `#[NoTwoFactorRequired]`
* `` @NoCSRFRequired` `` instead of `#[NoCSRFRequired]`
In the following some examples of configurations are given.
#### Showing an HTML page by the user[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#showing-an-html-page-by-the-user "Link to this heading")
A typical app needs an `index.html` page to show all content within. This page should be visible by all users in the instance. Therefore, you need to loosen the restriction from admins only (`#[NoAdminRequired]`). Additionally, as the user might not have a CSRF checker cookie set yet, the CSRF checks should be disabled (which is fine as this is a template response).
appName, 'main');
}
}
If the page should only be visible to the admin, you can keep the restrictive default by omitting the attribute `#[NoAdminRequired]`.
#### Getting data from the backend using AJAX requests[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#getting-data-from-the-backend-using-ajax-requests "Link to this heading")
Data for the frontend needs to be made available from the backend. Here, OCS is the suggested way to go. Here is the example from [OCS controllers](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#ocscontroller)
:
auth->isSuccessful here is just an
// example.
if (!$this\->auth\->isSuccessful()) {
$templateResponse\->throttle(); }
return $templateResponse;
}
}
A controller can also have multiple factors to brute force against. In this case you can specify multiple attributes and then in the throttle you specify the action which was violated. This is especially useful when a secret, in the sample below token, could be guessed on multiple endpoints e.g. a share token on the API level, preview endpoint, frontend controller, etc. while another secret (password), is specific to this one controller method.
shareManager\->getByToken($token)) {
$templateResponse\->throttle(\['action' \=> 'token'\]); }
// …
if (!$share\->verifyPassword($password)) {
$templateResponse\->throttle(\['action' \=> 'password'\]); }
return $templateResponse;
}
}
### Modifying the content security policy[](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html#modifying-the-content-security-policy "Link to this heading")
By default Nextcloud disables all resources which are not served on the same domain, forbids cross domain requests and disables inline CSS and JavaScript by setting a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Introducing_Content_Security_Policy)
. However if an app relies on third-party media or other features which are forbidden by the current policy the policy can be relaxed.
Note
Double check your content and edge cases before you relax the policy! Also read the [documentation provided by MDN](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Introducing_Content_Security_Policy)
To relax the policy pass an instance of the ContentSecurityPolicy class to your response. The methods on the class can be chained.
The following methods turn off security features by passing in **true** as the **$isAllowed** parameter
* **allowInlineScript** (bool $isAllowed)
* **allowInlineStyle** (bool $isAllowed)
* **allowEvalScript** (bool $isAllowed)
* **useStrictDynamic** (bool $isAllowed)
Trust all scripts that are loaded by a trusted script, see ‘script-src’ and ‘strict-dynamic’
* **useStrictDynamicOnScripts** (bool $isAllowed)
Trust all scripts that are loaded by a trusted script which was loaded using a `
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Dashboard — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Dashboard
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/dashboard.rst)
* * *
Dashboard[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#dashboard "Link to this heading")
=======================================================================================================================================
The dashboard app aims to provide the user with a general overview of their Nextcloud and shows information that is currently important.
App developers can integrate into the dashboard app and provide their own widgets.
Register a dashboard widget[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#register-a-dashboard-widget "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A dashboard widget is represented by a class implementing the OCP\\Dashboard\\IWidget interface. This class will be instantiated whenever the dashboard is loaded. Any bootstrap code that is needed for the widget can be implemented inside of the load method and will be called when the dashboard is loaded.
initialStateService \= $initialStateService;
$this\->l10n \= $l10n;
$this\->urlGenerator \= $urlGenerator;
}
/\*\*
\* @return string Unique id that identifies the widget, e.g. the app id
\*/
public function getId(): string {
return 'myappwidgetid';
}
/\*\*
\* @return string User facing title of the widget
\*/
public function getTitle(): string {
return $this\->l10n\->t('My app');
}
/\*\*
\* @return int Initial order for widget sorting
\* in the range of 10-100, 0-9 are reserved for shipped apps
\*/
public function getOrder(): int {
return 0;
}
/\*\*
\* @return string css class that displays an icon next to the widget title
\*/
public function getIconClass(): string {
return 'icon-class';
}
/\*\*
\* @return string|null The absolute url to the apps own view
\*/
public function getUrl(): ?string {
return $this\->urlGenerator\->linkToRouteAbsolute('myapp.view.index');
}
/\*\*
\* Execute widget bootstrap code like loading scripts and providing initial state
\*/
public function load(): void {
$this\->initialStateService\->provideInitialState('myapp', 'myData', \[\]);
\\OCP\\Util::addScript('myapp', 'dashboard');
}
}
The MyAppWidget class needs to be registered during the [app bootstrap](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
.
registerDashboardWidget(MyAppWidget::class);
}
public function boot(IBootContext $context): void {
}
}
### The IConditionalWidget interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iconditionalwidget-interface "Link to this heading")
The IConditionalWidget interface adds the **isEnabled** method to provide the option for a widget to opt-out later. While registering the widget the information whether or not a widget should be displayed to the specific user might not be available or to complex to calculate up front. In this case the IConditionalWidget allows you to check the conditions only when really needed.
public function isEnabled(): bool {
return false;
}
Provide a user interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#provide-a-user-interface "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
The user interface can be registered through the public OCA.Dashboard.register JavaScript method. The first parameter represents the widget id that has already been specified in the IWidget implementation. The callback parameter will be called to render the widget in the frontend. The user interface can be added to the provided DOM element el.
The following example shows how a Vue.js component could be used to render the widget user interface, however this approach works for any other framework as well as plain JavaScript:
import Dashboard from './components/Dashboard.vue'
document.addEventListener('DOMContentLoaded', () \=> {
OCA.Dashboard.register('myappwidgetid', (el) \=> {
const View \= Vue.extend(Dashboard)
const vm \= new View({
propsData: {},
store,
}).$mount(el)
})
})
Dashboard API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#dashboard-api "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
### Render dashboard widgets using the API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#render-dashboard-widgets-using-the-api "Link to this heading")
Added in version 27.1.
Dashboard widgets can be rendered in the browser using the dashboard API. This allows to render widgets without any JavaScript and frontend code. This new method is beneficial for performance as the widgets are rendered from API data using a generic vue.js component provided by the Dashboard app.
To render a widget using the new API, you need to implement the [OCP\\Dashboard\\IAPIWidgetV2](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#iapiwidgetv2)
interface. Optionally, you may implement the [OCP\\Dashboard\\IReloadableWidget](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#ireloadablewidget)
interface to have the widget reload periodically.
### Providing widgets to clients[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#providing-widgets-to-clients "Link to this heading")
To provide more information about your widget through the dashboard API for clients, you can implement those additional interfaces:
* IButtonWidget to add buttons to be rendered by the client in the widget
* IIconWidget to set the widget icon URL
* IOptionWidget to set additional options
* IAPIWidget to actually provide the widget content (the item list)
### The IButtonWidget interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-ibuttonwidget-interface "Link to this heading")
The IButtonWidget interface adds the **getWidgetButtons** method to provide a list of buttons to be displayed by the clients in the widget. Those buttons let you define actions that can be triggered from the widget in the clients.
There are 3 types of buttons:
* WidgetButton::TYPE\_NEW To let users create new elements in your app
* WidgetButton::TYPE\_MORE To let users see more information
* WidgetButton::TYPE\_SETUP If the widget requires some configuration
public function getWidgetButtons(string $userId): array {
return \[\
new WidgetButton(\
WidgetButton::TYPE\_NEW,\
'https://somewhere.org',\
$this\->l10n\->t('Create new element')\
),\
new WidgetButton(\
WidgetButton::TYPE\_MORE,\
'https://my.nextcloud.org/apps/your-app/',\
$this\->l10n\->t('More notifications')\
),\
new WidgetButton(\
WidgetButton::TYPE\_SETUP,\
'https://my.nextcloud.org/apps/settings/user',\
$this\->l10n\->t('Configure')\
),\
\];
}
### The IIconWidget interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iiconwidget-interface "Link to this heading")
The IIconWidget interface adds the **getIconUrl** method to provide the URL to the widget icon. In the following example it returns the URL to the img/app.svg file in your app.
public function getIconUrl(): string {
return $this\->urlGenerator\->getAbsoluteURL(
$this\->urlGenerator\->imagePath(Application::APP\_ID, 'app.svg')
);
}
### The IOptionWidget interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-ioptionwidget-interface "Link to this heading")
The IOptionWidget interface adds the **getWidgetOptions** method to provide additional widget options. It returns a WidgetOptions object which only contains the **roundItemIcons** boolean value for now. This tells the clients if the widget item icons should be rounded or kept as squares.
public function getWidgetOptions(): WidgetOptions {
return new WidgetOptions(true);
}
### The IAPIWidget interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iapiwidget-interface "Link to this heading")
If you want your widget content to be accessible with the dashboard API for Nextcloud clients, it must implement the OCP\\Dashboard\\IAPIWidget interface rather than OCP\\Dashboard\\IWidget. This interface contains an extra getItems method which returns an array of OCP\\DashboardModel\\WidgetItem objects.
/\*\*
\* @inheritDoc
\*/
public function getItems(string $userId, ?string $since \= null, int $limit \= 7): array {
return $this\->myService\->getWidgetItems($userId, $since, $limit);
}
OCP\\DashboardModel\\WidgetItem contains the item information. Its constructor is:
public function \_\_construct(string $title \= '',
string $subtitle \= '',
string $link \= '',
string $iconUrl \= '',
string $sinceId \= '');
* title: The main widget text content
* subtitle: The secondary text content
* link: A link to the target resource
* iconUrl: URL to a square icon (svg or jpg/png of at least 44x44px)
* sinceId: Item ID or timestamp. The client will then send the latest known sinceId in next dashboard API request.
Added in version 27.1.
* overlayIconUrl: Small overlay icon to show in the bottom right corner of iconUrl. This is used by the activity widget to show the activity type icon.
### The IAPIWidgetV2 interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iapiwidgetv2-interface "Link to this heading")
If you want to render a widget in the browser using this API you must implement the OCP\\Dashboard\\IAPIWidgetV2 interface. The widget registration does not change compared to the old method. The type of a widget will be detected automatically during the registration. When migrating old, JavaScript based widgets the **load** method should be left empty.
This interface adds a single method **getItemsV2** which returns OCP\\Dashboard\\Model\\WidgetItems.
/\*\*
\* @inheritDoc
\*/
public function getItemsV2(string $userId, ?string $since \= null, int $limit \= 7): WidgetItems {
return $this\->myService\->getWidgetItemsV2($userId, $since, $limit);
}
OCP\\DashboardModel\\WidgetItems contains the all items and additional meta information to render the widget. Its constructor is:
public function \_\_construct(
private array $items \= \[\],
private string $emptyContentMessage \= '',
private string $halfEmptyContentMessage \= '',
)
* items: An array of [OCP\\DashboardModel\\WidgetItem](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#widgetitem)
.
* emptyContentMessage: The message to show if no items are available.
* halfEmptyContentMessage: An optional message to show above the item list. This is useful if there are no important items but you still want to show some items to the user. Have a look at the following example from the Talk app:
[](https://docs.nextcloud.com/server/latest/developer_manual/_images/talk-widget-half-empty-content.png)
Here is a full example of a widget that implements the OCP\\Dashboard\\IAPIWidgetV2 interface:
l10n\->t('My blazingly fast widget');
}
/\*\*
\* @inheritDoc
\*/
public function getOrder(): int {
return 0;
}
/\*\*
\* @inheritDoc
\*/
public function getIconClass(): string {
return 'icon-class';
}
/\*\*
\* @inheritDoc
\*/
public function getIconUrl(): string {
return $this\->urlGenerator\->getAbsoluteURL(
$this\->urlGenerator\->imagePath('blazinglyfast', 'icon.svg')
);
}
/\*\*
\* @inheritDoc
\*/
public function getUrl(): ?string {
return $this\->urlGenerator\->linkToRouteAbsolute('blazinglyfast.view.index');
}
/\*\*
\* @inheritDoc
\*/
public function load(): void {
// No need to provide initial state or inject javascript code anymore
}
/\*\*
\* @inheritDoc
\*/
public function getItemsV2(string $userId, ?string $since \= null, int $limit \= 7): WidgetItems {
// TODO
$items \= \[/\* fancy items \*/\];
return new WidgetItems(
$items,
empty($items) ? $this\->l10n\->t('No items') : '',
);
}
/\*\*
\* @inheritDoc
\*/
public function getWidgetButtons(string $userId): array {
return \[\
new WidgetButton(\
WidgetButton::TYPE\_MORE,\
$this\->urlGenerator\->linkToRouteAbsolute('blazinglyfast.view.index'),\
$this\->l10n\->t('More items'),\
),\
\];
}
/\*\*
\* @inheritDoc
\*/
public function getReloadInterval(): int {
return 60;
}
}
### The IReloadableWidget interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-ireloadablewidget-interface "Link to this heading")
The IReloadableWidget interface adds the **getReloadInterval** method to provide a periodic reload interval in seconds. New items will be requested from the OCS API after this interval to refresh the widget. Internally, the **getItemsV2** method will be called to get the new items.
public function getReloadInterval(): int {
// Reload data every minute
return 60;
}
Note
This interface requires a widget to implement the OCP\\Dashboard\\IAPIWidgetV2 interface and won’t work with old widgets.
### Use the API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#use-the-api "Link to this heading")
The list of enabled widgets can be requested like that:
curl \-u user:passwd https://my.nextcloud.org/ocs/v2.php/apps/dashboard/api/v1/widgets \\
\-H "Accept: application/json" \\
\-X GET
Example response:
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"spreed": {
"id": "spreed",
"title": "Talk mentions",
"order": 10,
"icon\_class": "dashboard-talk-icon",
"icon\_url": "https://my.nextcloud.org/apps/spreed/img/app-dark.svg",
"widget\_url": "https://my.nextcloud.org/index.php/apps/spreed/",
"item\_icons\_round": true,
"buttons": \[\
{\
"type": "more",\
"text": "More unread mentions",\
"link": "https://my.nextcloud.org/index.php/apps/spreed/"\
}\
\]
},
"github\_notifications": {
"id": "github\_notifications",
"title": "GitHub notifications",
"order": 10,
"icon\_class": "icon-github",
"icon\_url": "https://my.nextcloud.org/apps/integration\_github/img/app-dark.svg",
"widget\_url": "https://my.nextcloud.org/index.php/settings/user/connected-accounts",
"item\_icons\_round": true,
"buttons": \[\
{\
"type": "more",\
"text": "More notifications",\
"link": "https://github.com/notifications"\
}\
\]
},
}
}
}
The items list for each enabled widgets can be requested like that:
curl \-u user:passwd http://my.nc/ocs/v2.php/apps/dashboard/api/v1/widget-items \\
\-H Content-Type:application/json \\
\-X GET \\
\-d '{"sinceIds":{"myappwidgetid":"2021-03-22T15:01:10Z","my\_other\_appwidgetid":"333"}}'
If your client periodically gets widget items content with this API, include the latest sinceId for each widget to avoid getting the items you already have.
Example response:
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"github\_notifications": \[\
{\
"subtitle": "nextcloud-docker-dev#87",\
"title": "Improve getting started",\
"link": "https://github.com/juliushaertl/nextcloud-docker-dev/pull/87",\
"iconUrl": "https://my.nextcloud.org/index.php/apps/integration\_github/avatar/juliushaertl",\
"sinceId": "2022-10-13T12:34:19Z"\
},\
{\
"subtitle": "integration\_github",\
"title": "v1.0.11",\
"link": "https://github.com/nextcloud/integration\_github/releases",\
"iconUrl": "https://my.nextcloud.org/index.php/apps/integration\_github/avatar/nextcloud",\
"sinceId": "2022-10-13T12:32:04Z"\
},\
{\
"subtitle": "text#3209",\
"title": "Rich workspaces: If there is no Readme.md, don’t show editor placeholder but move into \\"+\\" menu",\
"link": "https://github.com/nextcloud/text/issues/3209",\
"iconUrl": "https://my.nextcloud.org/index.php/apps/integration\_github/avatar/nextcloud",\
"sinceId": "2022-10-13T12:14:39Z"\
}\
\],
"spreed": \[\
{\
"subtitle": "- Send chat messages without notifying the recipients in case it is not urgent",\
"title": "Talk updates ✅",\
"link": "https://my.nextcloud.org/index.php/call/hw39yxkp",\
"iconUrl": "https://my.nextcloud.org/core/img/actions/group.svg",\
"sinceId": ""\
},\
{\
"subtitle": "@roberto What's up?",\
"title": "Jane",\
"link": "https://my.nextcloud.org/index.php/call/z87agy2o",\
"iconUrl": "https://my.nextcloud.org/index.php/avatar/toto/64",\
"sinceId": ""\
}\
\]
}
}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Foundations — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Interface & interaction design](https://docs.nextcloud.com/server/latest/developer_manual/design/index.html)
* Foundations
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/design/foundations.rst)
* * *
Foundations[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#foundations "Link to this heading")
=====================================================================================================================================
There are several design elements that are common to all Nextcloud apps. If you are developing for a platform that has its own design specifications, for example Android, it would be a good idea to keep those in mind while designing your app.
For web apps, there is the [Vue library](https://nextcloud-vue-components.netlify.app/)
and the [Penpot design kit](https://design.penpot.app/#/view/db3839da-807b-8052-8002-576401e9a375?page-id=db3839da-807b-8052-8002-576401e9a376§ion=interactions&index=0&share-id=11fde340-21f4-802e-8002-8d8d305e7ab5)
.
Color[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#color "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------
[Penpot colors](https://design.penpot.app/#/view/db3839da-807b-8052-8002-576401e9a375?page-id=3f784c86-6c27-80c6-8002-6ab128f3ffe2§ion=interactions&index=3&share-id=11fde340-21f4-802e-8002-8d8d305e7ab5)
### Primary color[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#primary-color "Link to this heading")

#0082C9[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id6 "Link to this image")
While this is the primary color associated with Nextcloud and can be used to draw attention to an element, it is best to limit the usage of this to primary actions and other important elements.
Note
The primary color can be customized by admins through theming, but the default experience will be Nextcloud blue. If the primary color is themed to something very light like a shade of yellow, the text or header icons will be inverted to dark automatically.
* On web: `var(--color-primary-element)`
* Android: uses default Material Design colors
* iOS: [systemFill](https://developer.apple.com/documentation/uikit/uicolor/3255070-systemfill)
* Desktop: [default Qt guidelines](https://doc.qt.io/qt-5/qpalette.html#ColorRole-enum)
### Background color[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#background-color "Link to this heading")
| | |
| --- | --- |
| 
Background for light theme: #FFFFFF[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id7 "Link to this image") | 
Background for dark theme: #181818[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id8 "Link to this image") |
Nextcloud apps have a light and a dark theme, with appropriately chosen colors for all elements.
* On web: `var(--color-main-background)`
* Android: uses default Material Design colors
* iOS: [systemBackground](https://developer.apple.com/documentation/uikit/uicolor/3173140-systembackground)
* Desktop: [default Qt guidelines](https://doc.qt.io/qt-5/qpalette.html#ColorRole-enum)
### Text color[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#text-color "Link to this heading")
| | |
| --- | --- |
| 
Text in light theme: #222222[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id9 "Link to this image") | 
Text in dark theme: #D8D8D8[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id10 "Link to this image") |
This is the main color for the text in light theme, and in dark theme.
* On web: `var(--color-main-text)`
* Android: uses default Material Design color “high emphasis”
* iOS: [label](https://developer.apple.com/documentation/uikit/uicolor/3173131-label)
(in UITextView, leave the default textColor)
* Desktop: [default Qt guidelines](https://doc.qt.io/qt-5/qpalette.html#ColorRole-enum)
| | |
| --- | --- |
| 
Secondary text in light theme: #767676[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id11 "Link to this image") | 
Secondary text in dark theme: #8C8C8C[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id12 "Link to this image") |
In addition, a softer color is used for secondary text like sublines, timestamps, and similar.
* On web:`var(--color-text-maxcontrast)`
* Android: uses default Material Design color “medium emphasis”
* iOS: [secondaryLabel](https://developer.apple.com/documentation/uikit/uicolor/3173136-secondarylabel)
* Desktop: [default Qt guidelines](https://doc.qt.io/qt-5/qpalette.html#ColorRole-enum)
### Status and indicators[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#status-and-indicators "Link to this heading")
| | | | |
| --- | --- | --- | --- |
| 
Info: #006AA3[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id13 "Link to this image") | 
Success: #46BA61[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id14 "Link to this image") | 
Error: #E9322D[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id15 "Link to this image") | 
Warning: #ECA700[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#id16 "Link to this image") |
Interface elements associated with a status like info, success, error, or warning may also be colored to communicate the action better.
While interface elements like buttons are colored differently depending on their action, the color of the text in that element is almost always either of the main text colors, that is light or dark.
* On web:
* Info color: `var(--color-info)`
* Success color: `var(--color-success)`
* Warning color: `var(--color-warning)`
* Error color: `var(--color-error)`
* Android: Material Design guidelines
* iOS: [Apple HIG colors](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/color/)
* success: systemGreen
* error: systemRed
* Desktop: [default Qt guidelines](https://doc.qt.io/qt-5/qpalette.html#ColorRole-enum)
Typography[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#typography "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------
[Penpot typography](https://design.penpot.app/#/view/db3839da-807b-8052-8002-576401e9a375?page-id=3f784c86-6c27-80c6-8002-6ab128f3ffe2§ion=interactions&index=1&share-id=11fde340-21f4-802e-8002-8d8d305e7ab5)
To ensure compatibility with different platforms, Nextcloud apps always use the native system font.
For legibility, make sure that the text in your content uses:
* **Bold** for emphasis
* A line height between 130% and 150%
* The default tracking of the font
* No _italics_ or UPPER CASE as these text styles are less legible
The text sizes for the different platforms are:
* Web: 16px for main text and sublines, **20px bold** for headings
* Android: 14sp for main text, 16sp for headings
* iOS: values from [Dynamic Type Sizes, for size Large (Default)](https://developer.apple.com/design/human-interface-guidelines/ios/visual-design/typography#dynamic-type-sizes)
* Desktop: [default Qt guidelines](https://doc.qt.io/qt-5/qpalette.html#ColorRole-enum)
Icons[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#icons "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------
[Penpot icons](https://design.penpot.app/#/view/db3839da-807b-8052-8002-576401e9a375?page-id=3f784c86-6c27-80c6-8002-6ab128f3ffe2§ion=interactions&index=0&share-id=11fde340-21f4-802e-8002-8d8d305e7ab5)

Icons can be used to communicate the intent of an action, or to provide visual interest to the screen. We use monochrome icons on all platforms: [Material Symbols (not Material Icons, and 20 px default outlined)](https://fonts.google.com/icons?icon.set=Material+Symbols&selected=Material+Symbols+Outlined:search:FILL@0;wght@400;GRAD@0;opsz@20&icon.size=20)
for web, Android, Windows and Linux, and [SF Symbols (default weight, scale and variant)](https://developer.apple.com/sf-symbols/)
for iOS and macOS.
This is except for the icon of the app itself, which can be a custom icon. Most use an app icon from Material Symbols as well though to keep consistency.
Make sure to:
* Not overuse icons
* When possible, use text together with icons so it’s clear what they refer to
* For special cases like warnings, combine the icon with color to enhance its visibility
Naming[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#naming "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------
To be immediately understandable, we choose app names which are generic and easily translatable. Additionally, they are short and easily fit in the top navigation without being cut off.
Files, Contacts, Calendar, and Mail do not need further explanation, which is why we recommend to choose a self-explanatory app name.
Further good examples of this: Notes, Bookmarks, Maps, Forms, Tasks, Music.
Wording[](https://docs.nextcloud.com/server/latest/developer_manual/design/foundations.html#wording "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------
The wording and language in your app sets the tone and approachability of your app.
* Nextcloud should always be written out, and only with a capital N. Not “NextCloud” or “Nc”.
* Be friendly and approachable, not condescending.
* Use understandable language, not technical jargon. For example, “link” is much better than “URL”, and explaining errors is better than showing error codes.
* Don’t write in ALL CAPS, as it is not as readable and comes off as shouting and aggressive. Also use Sentence case and not Capital Case, with the exception of product names like Nextcloud Talk, Nextcloud Hub, etc.
* We are a community, so better write “We are happy to announce” instead of “I am happy to announce”.
* If your app content is empty, it can be helpful to add an engaging message. “Add or import your first bookmark!” is much nicer than “No bookmarks yet”.
* Try to avoid using “my” or “your” like in “My files” or “Your files”, instead using “All files”. For longer sentences where it cannot be avoided, use “your”, never “my”.
* Use gender neutral language. This [international guide to gender-inclusive writing](https://uxcontent.com/the-international-guide-to-gender-inclusive-writing/)
contains info and examples on gender neutral wording for different languages.
* Use full names instead of only first names while addressing the person using your app.
* For any “Delete” action, give context to what it will delete, like “Delete conversation” or “Delete user” so that it is clear specifically for this destructive action.
* Keep language short and concise, and keep in mind that it should be easily translatable.
* Make sure to spellcheck anything you write.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Performance considerations — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Performance considerations
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/performance.rst)
* * *
Performance considerations[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#performance-considerations "Link to this heading")
===========================================================================================================================================================================
This document introduces some common considerations and tips on improving performance of Nextcloud. Speed of Nextcloud is important - nobody likes to wait and often, what is _just slow_ for a small amount of data will become _unusable_ with a large amount of data. Please keep these tips in mind when developing for Nextcloud and consider reviewing your app to make it faster.
PHP Performance[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#php-performance "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------
* Autoloader: Consider using an [optimized class loader](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/classloader.html#app-custom-classloader)
. The application code does not have to change for this optimization.
* Heavy background jobs: Consider marking [background jobs](https://docs.nextcloud.com/server/latest/developer_manual/basics/backgroundjobs.html#app-backgroundjobs)
as [time insensitive](https://docs.nextcloud.com/server/latest/developer_manual/basics/backgroundjobs.html#app-backgroundjobs-time-sensitivity)
if they can be run at off-peak times with lower system load, e.g. at night.
Database performance[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#database-performance "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
The database plays an important role in Nextcloud performance. The general rule is: database queries are very bad and should be avoided if possible. The reasons for that are:
* Roundtrips: Bigger Nextcloud installations have the database not installed on the application server but on a remote dedicated database server. The problem is that database queries then go over the network. These roundtrips can add up significantly if you have a lot of queries.
* Speed. A lot of people think that databases are fast. This is not always true if you compare it with handling data internally in PHP or in the filesystem or even using key/value based storages. So every developer should always double check if the database is really the best place for the data.
* Scalability. If you have a big Nextcloud cluster setup you usually have several Nextcloud/Web servers in parallel and a central database and a central storage. This means that everything that happens on the Nextcloud/PHP side can parallelize and can be scaled. Stuff that is happening in the database and in the storage is critical because it only exists once and can’t be scaled so easily.
We can reduce the load on the database by:
1. Making sure that every query uses an index.
2. Reducing the overall number of queries.
3. If you are familiar with cache invalidation you can try caching query results in PHP.
There a several ways to monitor which queries are actually executed on the database.
With MySQL it is very easy with just a bit of configuration:
1. Slow query log.
If you put this into your my.cnf file, every query that takes longer than one second is logged to a logfile:
slow\_query\_log \= 1
slow\_query\_log\_file \= /var/log/mysql/mysql\-slow.log
long\_query\_time\=1
If a query takes more than a second we have a serious problem of course. You can watch it with tail -f /var/log/mysql/mysql-slow.log while using Nextcloud.
2. log all queries.
If you reduce the long\_query\_time to zero then every statement is logged. This is super helpful to see what is going on. Just do a tail -f on the logfile and click around in the interface or access the WebDAV interface:
slow\_query\_log \= 1
slow\_query\_log\_file \= /var/log/mysql/mysql\-slow.log
long\_query\_time\=0
3. log queries without an index.
If you increase the long\_query\_time to 100 and add log-queries-not-using-indexes, all the queries that are not using an index are logged. Every query should always use an index. So ideally there should be no output:
log\-queries\-not\-using\-indexes
slow\_query\_log \= 1
slow\_query\_log\_file \= /var/log/mysql/mysql\-slow.log
long\_query\_time\=100
### Writing scalable transactions[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#writing-scalable-transactions "Link to this heading")
Database queries and transactions have to work efficiently no matter the size of the Nextcloud installations. They have to work with simple SQLite, a single node Postgres and a MariaDB Galera cluster to give some examples.
#### Database clusters[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#database-clusters "Link to this heading")
Single instance database offer strong consistency. Clusters can offer it too, but it comes with a performance penalty and admins occasionally choose to relax these guarantees to increase throughput. One of these allowed inconsistencies can happen on read/write split clusters, where some nodes handle only read (SELECT) operations while other can handle read and write (SELECT, INSERT, UPDATE and DELETE). Keeping replica nodes in sync with primary nodes is expensive. Allowing a few milliseconds of delay for the data to propagate from primary to replica allows the primary to process more queries.
Added in version 29: Nextcloud installations can have a primary connection and a number of replica connections. The database abstraction will automatically split read and write operations. Reads go to a replica, unless they happen in a transaction. Writes always go to the primary. As soon as a table has been written to, subsequent reads go to the primary too.
Other installations do this split inside the cluster or with a database load balancer that sends queries to one or another node based on criteria, round robin, etc. This means that Nextcloud can’t always influence where queries are executed.
It is important for Nextcloud developers to keep this in mind when writing database queries, especially when it is a series of queries. The next sections cover common anti-patterns and solutions.
#### Reading data that has just been written[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#reading-data-that-has-just-been-written "Link to this heading")
A common pattern that works fine with small databases but falls apart on overloaded clusters are causal reads. These happen when a Nextcloud process INSERTs new data and reads that data right away. This can be obvious to spot in the code, but sometimes this is also obfuscated because of event listeners that react on new data.
There are two patterns to avoid the “dirty” read:
> 1. **Wrap the write+read operation in a transaction**. Nextcloud’s read/write split, but also other database cluster load balancers will ensure that the queries of a transactions go to one single database node of a cluster. That ensures that data written is instantly available to be read back. This approach guarantees consistency, but puts additional load on the primary node because it has to execute the read operation too. This is best used in contained code blocks. Do not span transactions for event listeners because their execution might lead to [long transactions](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#performance-long-transactions)
> and locking issues.
>
> 2. **Avoid the read operation**. If the code allows it, avoid the read operation all together. You should know what was just written. If you need the auto increment ID, use the database’s _last insert ID_ feature. Proceed with this data, pass it to event listeners, etc. This approach guarantees consistency, too, but also improves overall performance.
>
Tip
Nextcloud can help you identify read after write without the need to set up a cluster for your development environment. If you change the loglevel to 0 (debug), dirty reads will trigger a log entry. Monitor the log when testing your code.
Look out for messages like ``dirty table reads: SELECT `id` FROM `*PREFIX*jobs` WHERE (`class` = :dcValue1) AND (`argument_hash` = :dcValue2) LIMIT 1``. Use the log entry’s _trace_ to locate the code that executed the query.
Be aware that the dirty read detection is not perfect and might wrongly log a dirty read when you write and read unrelated data. As an example, you may read user _alice_, update her data, and then read _bob_’s data and do the same. Even if the database replicates slow, you will not read data that doesn’t exist yet. Since Nextcloud tracks on a table level, it still warns.
#### Long transactions[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#long-transactions "Link to this heading")
Transactions are crucial for changes that belong together but they can cause problems under load. That’s because the longer the transaction is open, the more other queries may have to wait for a lock to be released. This can lead to contention, timing out requests and deadlocks. So use transaction wisely and try to keep them as short as possible. Don’t mix them database operations with file system operations, for example.
Tip
Nextcloud can help you identify slow transactions. If you change the loglevel to 0 (debug), slow transaction will cause a log message at commit/rollback.
Look out for messages like `Transaction took longer than 1s: 7.1270351409912` and `Transaction rollback took longer than 1s: 1.2153599501`.
### Measuring performance[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#measuring-performance "Link to this heading")
If you do bigger changes in the architecture or the database structure you should always double check the positive or negative performance impact.
The recommendation is to automatically do 10000 PROPFINDs or file uploads, measure the time and compare the time before and after the change.
Cached data[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#cached-data "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------
Starting from Nextcloud 26, user and group display names now are cached. Use the `IUserManager::getDisplayName` or `IGroupManager::getDisplayName` functions to avoid roundtrips to the database.
Getting help[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#getting-help "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
If you need help with performance or other issues please ask on our [forums](https://help.nextcloud.com/)
.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Profile — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Profile
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/profile.rst)
* * *
Profile[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profile.html#profile "Link to this heading")
=================================================================================================================================
The user profile presents the information of a user including their full name, profile picture, organisation, role, location, biography, headline, as well as actionable information that we call profile actions. These actions can include starting a [Nextcloud Talk](https://nextcloud.com/talk/)
chat with the user, sending an email, visiting their website, opening their Twitter profile, calling their phone number, scheduling an appointment, and more.
App developers can integrate into profile and provide their own actions.
Register a profile action[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profile.html#register-a-profile-action "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
A profile action is represented by a class implementing the `OCP\\Profile\\ILinkAction` interface. This class is instantiated whenever the user profile is loaded.
accountManager \= $accountManager;
$this\->l10n \= $l10n;
$this\->urlGenerator \= $urlGenerator;
}
/\*\*
\* Preload the user specific value required by the action
\*
\* e.g. the email is loaded for the email action and the userId for the Talk action
\*
\* @since 23.0.0
\*/
public function preload(IUser $targetUser): void {
$this\->targetUser \= $targetUser;
}
/\*\*
\* Returns the app ID of the action
\*
\* e.g. 'spreed'
\*
\* @since 23.0.0
\*/
public function getAppId(): string {
return 'my\_app\_id';
}
/\*\*
\* Returns the unique ID of the action
\*
\* \*For account properties this is the constant defined in lib/public/Accounts/IAccountManager.php\*
\*
\* e.g. 'email'
\*
\* @since 23.0.0
\*/
public function getId(): string {
return 'my\_unique\_action';
}
/\*\*
\* Returns the translated unique display ID of the action
\*
\* Should be something short and descriptive of the action
\* as this is seen by the end-user when configuring actions
\*
\* e.g. 'Email'
\*
\* @since 23.0.0
\*/
public function getDisplayId(): string {
return $this\->l10n\->t('My unique action');
}
/\*\*
\* Returns the translated title
\*
\* e.g. 'Mail user@domain.com'
\*
\* Use the L10N service to translate it
\*
\* @since 23.0.0
\*/
public function getTitle(): string {
return $this\->l10n\->t('Ping %s', \[$this\->targetUser\->getDisplayName()\]);
}
/\*\*
\* Returns the priority
\*
\* \*Actions are sorted in ascending order\*
\*
\* e.g. 60
\*
\* @since 23.0.0
\*/
public function getPriority(): int {
return 60;
}
/\*\*
\* Returns the URL link to the 16\*16 SVG icon
\*
\* @since 23.0.0
\*/
public function getIcon(): string {
return $this\->urlGenerator\->getAbsoluteURL($this\->urlGenerator\->imagePath('my\_app\_id', 'actions/my\_unique\_action.svg'));
}
/\*\*
\* Returns the target of the action,
\* if null is returned the action won't be registered
\*
\* e.g. 'mailto:user@domain.com'
\*
\* @since 23.0.0
\*/
public function getTarget(): ?string {
return $this\->urlGenerator\->linkToRouteAbsolute('my\_app\_id.Page.index') . '?pingUser=' . $this\->targetUser\->getUID();
}
}
The `MyProfileAction` class needs to be registered during the [app bootstrap](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
.
registerProfileLinkAction(MyProfileAction::class);
}
public function boot(IBootContext $context): void {
}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# PSR — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* PSR
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/psr.rst)
* * *
PSR[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr "Link to this heading")
=====================================================================================================================
On this page you find information about the implemented [php standards recommendations](https://www.php-fig.org/psr/)
in Nextcloud.
PSR-0: Autoloading[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-0-autoloading "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
This standard has been deprecated and will be removed in Nextcloud 27. Please see the [PSR-4 section](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr4)
instead.
PSR-3: Logger Interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-3-logger-interface "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
Added in version 19.
The dependency injection container can inject an instance of a `\Psr\Log\LoggerInterface`. The [PSR-3](https://www.php-fig.org/psr/psr-3/)
implementation shall easy the integration of 3rd party libraries that require the [PSR-3](https://www.php-fig.org/psr/psr-3/)
logger.
Changed in version 21: Nextcloud ships version 1.1.3
Changed in version 23: Nextcloud ships version 1.1.4
Changed in version 30: Nextcloud ships version 2.0.0
Changed in version 31: The `\Psr\Log\LoggerInterface` fully replaced the Nextcloud internal logging methods.
PSR-4: Autoloading[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-4-autoloading "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
The PSR-4 standard describes how class files should be named, so Nextcloud can automatically load them. See the [classloader docs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/classloader.html#appclassloader)
for details.
PSR-11: Container Interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-11-container-interface "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Added in version 20.
The dependency injection container follows the [PSR-11](https://www.php-fig.org/psr/psr-11/)
container interface, so you may type-hint `\Psr\Container\ContainerInterface` whenever you want an instance of a container and use `has($id)` to check for existence and `get($id)` to retrieve an instance of a service. See the [dependency injection docs](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
for details.
Changed in version 22: Nextcloud ships version 1.1.1
Changed in version 27: Nextcloud ships version 2.0.2
PSR-20: Clock[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-20-clock "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------
Added in version 27.
The `\OCP\AppFramework\Utility\ITimeFactory` class follows the [PSR-20](https://www.php-fig.org/psr/psr-20/)
clock interface, so you may type-hint `\PSR\Clock\ClockInterface` and then use the `now()` method whenever you want to get the current time. You can also change the timezone for the to be returned `\DateTimeImmutable` instance, by getting a new `ITimeFactory` from `ITimeFactory::withTimeZone()`.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Maintainers — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/index.html)
* Maintainers
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_publishing_maintenance/maintainer.rst)
* * *
Maintainers[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/maintainer.html#maintainers "Link to this heading")
========================================================================================================================================================
The role of a Nextcloud app maintainer is to oversee all processes around an app. The responsibilities are:
* Triage bug reports
* Make sure reported bugs are reproducible, ask for more info if necessary
* Check for duplicates
* Close resolved tickets
* Manage pull requests
* Ensure pull request receive a review in reasonable time
* Merge pull requests that pass the peer review and all continuous integration checks
* Trigger backports if applicable
* Manage releases
* Ensure pre-releases are ready for deployment in pre-production of Nextcloud server
* Ensure compatible releases are ready for deployments of Nextcloud server releases
* Manage vulnerabilities
* Monitor vulnerable dependencies, e.g. through Github security alerts, and release updates timely
* Coordinate disclosed vulnerabilities with the Nextcloud security team
To avoid the so called [bus factor](https://en.wikipedia.org/wiki/Bus_factor)
, it is highly recommended to have more than one maintainer for each app. Apps can have one primary maintainer and one or more backup maintainers. For transparency, it can make sense to declare the maintainers of an app in the app’s repository README file, so that others know whom to contact.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Release process — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/index.html)
* Release process
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_publishing_maintenance/release_process.rst)
* * *
Release process[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#release-process "Link to this heading")
=====================================================================================================================================================================
Overview[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#overview "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------
This page documents the overall process and tasks of releasing a Nextcloud app to the public, as well as preparation and follow-up tasks.
Not all of the described steps will apply to all apps. Some require fewer steps, for others there is some additional work to do. Adjust the process accordingly.
Before the release[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#before-the-release "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Change tracking[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#change-tracking "Link to this heading")
If the app uses some sort of tracking like Github milestones, projects or similar, make sure that app scheduled changes have been merged into the target branch.
At this point you can probably assign a release date (if not set already) on the milestone and close it.
### Versioning[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#versioning "Link to this heading")
Each update of an app needs a new, higher version number. Before preparing a specific release, the maintainer has to decide what version number the new release will get.
It is highly recommended that apps follow [semantic versioning](https://semver.org/)
(semver). This schema allows admins and users to better understand what type of change they can expect when an app update is available.
Applying semver on Nextcloud apps gives three types of updates: major, minor and patch.
#### Patch updates[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#patch-updates "Link to this heading")
Increment the patch version number when
* A bug gets fixed
* Translations are added or fixed, but **not** removed
Tip
Example: the app is at version 3.7.2. The next patch version will be 3.7.3.
#### Minor updates[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#minor-updates "Link to this heading")
Increment the minor version number when
* There is a new feature
* A new major version of Nextcloud will be supported
* A new major or minor version of PHP will be supported
* An additional database type is supported
* A Nextcloud version that has reached EOL is dropped, e.g. when Nextcloud 19 is removed
* A PHP version that has reached EOL is dropped, e.g. when PHP 7.3 is removed
* Any other change that keeps the app compatible with previously compatible environments (forward compatibility)
Tip
Example: the app is at version 3.7.2. The next minor version will be 3.8.0.
#### Major update[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#major-update "Link to this heading")
Increment the major version number when
* The app drops support for a major version of Nextcloud that hasn’t reached EOL, e.g. when Nextcloud 23 support is removed and the app now requires Nextcloud 24 or newer
* The app drops support for a major or minor version of PHP that hasn’t rached EOL, e.g. when PHP 8.0 is removed and the app now requires PHP 8.1 or newer
* A database type is no longer supported, e.g. when the maintainer decides to stop SQLite support
* Any other change that makes the app incompatible with a previously compatible environment (breaking change)
Tip
Example: the app is at version 3.7.2. The next major version will be 4.0.0.
### Change log[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#change-log "Link to this heading")
If the app [keeps a change log](https://keepachangelog.com/en/1.0.0/)
(e.g. CHANGELOG.md in the project root) it’s time to update it with all **added**, **changed** and **fixed** items.
Tip
Use `git log v3.7.1..HEAD --pretty=oneline | grep -v tx-robot | grep -v "Merge " | grep -v "Bump "` on the target release branch to get a compact list of all changes since the v3.7.1 release. Adjust this to your previous release version number.
### Pre-releases[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#pre-releases "Link to this heading")
Optionally maintainers may chose to pre-release their apps on the app store for early adopters and testers. The precise periodization is up to the maintainer. Common periods include **alpha**, **beta** and **rc** (release candidate) epochs.
The release process is identical to the one of a final release, only the version number has a suffix.
Tip
Example: the app will be released as version 3.7.2. Therefore there might be a **v3.7.2-alpha.1**, **v3.7.2-beta.1**, **v3.7.2-rc.1**, **v3.7.2-rc.2** and the final **v3.7.2**.
The updater channel defines if pre-releases are installed by the server. This setting can be found in the admin setting or in the `config/config.php` file. The server will install pre-releases if its update channel is set `beta`, `daily`, or `git`. For all other settings, pre-releases will not be installed.
Tip
Don’t publish the pre-releases as nightly version on the app store or Nextcloud installations won’t be able to update. Releasing with any (alphanumeric) suffix is sufficient to mark the release as not production ready and instances are still able to update to it.
### Nightly releases[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#nightly-releases "Link to this heading")
Additionally to publishing pre-releases, the maintainers can release nightly releases. These are considered even less stable than pre-releases. In the app store, such nightly releases are marked separately.
Nightly releases will be automatically installed by servers if the update channels is set to `daily` or `git`. Any other setting will make the server ignore nightly releases.
Tip
The server uses internally the PHP function `version_compare`. Consider the version number of a nightly version carefully, so that newly published (pre-) releases are considered newer than the nightly ones.
The release[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#the-release "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
From an abstract point of view the main part of doing a release is transforming the source code into an installable software component.
This part is typically scripted and highly depends on the type of app. The following list is incomplete but should give a rough idea of what steps a release script should contain:
* Switch to your target branch and pull the latest changes
* Tag the release in Git and push your local changes, if any
* Install all [dependencies](https://docs.nextcloud.com/server/latest/developer_manual/app_development/dependency_management.html#app-dependencies)
* Run `composer i --no-dev` if the app uses [Composer](https://docs.nextcloud.com/server/latest/developer_manual/app_development/dependency_management.html#app-composer)
* Run `npm ci` if the app uses [npm](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html#app-npm)
* Build compiled artifacts
* [Build production scripts for the front-end](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html#app-npm-build)
* Run any code generation (e.g. through a [Composer script](https://docs.nextcloud.com/server/latest/developer_manual/app_development/dependency_management.html#app-composer)
)
* Remove development files
* Remove any kind of configuration files (`composer.*`, `package.json`, `package-lock.json`, `.babelrc`, and so on) that are not required in production
* Remove source code that is not required in production, e.g. JavaScript that is compiled into a bundle
* Remove tests
* [Sign the release files](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/code_signing.html#app-code-signing)
to generate an appinfo/signature.json
* Package the rest into a .tar.gz tarball
* Upload the tarball for distribution, e.g. as a Github release artifact or a dedicated download server
* [Publish](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#app-store-publishing)
on the app store
After the release[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#after-the-release "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### Branch off[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#branch-off "Link to this heading")
If the maintainer of the app keeps stable branches to which bug fixes are backported, any major or minor release requires a branching off the current main branch.
### Prepare follow-up releases[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#prepare-follow-up-releases "Link to this heading")
The target milestone was closed in the release preparation. Now it’s time to create a new milestone for the next release(s).
Shipped Apps[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#shipped-apps "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
The majority of apps is distributed via the Nextcloud app store. A few apps are bundled and shipped with Nextcloud. There are a few things to keep in mind for them.
### Git branch management[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#git-branch-management "Link to this heading")
The release script simply git-clones app repositories. Repositories of shipped apps need branches to correspond to the branches in the [Nextcloud server repository](https://github.com/nextcloud/server)
:
* `master` branch is used to create the daily builds of Nextcloud
* `stable*` branches are used to build stable releases, e.g. `stable24` for Nextcloud 24.x.y.
Because apps are just cloned, it is not possible to have a build step for shipped apps. Shipped apps have to _vendor_ all their release artifacts.
Example:
* App uses `composer` dependencies: commit all production dependencies in the `vendor` directory
* App uses `npm` dependencies and front-end build tools: commit all front-end artifacts in the `js` directory
### Versioning[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#id1 "Link to this heading")
Since every `stable*` branch targets only one major version of Nextcloud and drops the previous one, it’s best to have one major version of the app per stable branch. See [app versioning](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#app-versioning)
for details.
Example:
* `master`: Version 8.0.0, targeting Nextcloud 27
* `stable26`: Version 7.0.0, targeting Nextcloud 26
* `stable25`: Version 6.0.0, targeting Nextcloud 25
Backported fixes increase the patch version on a stable branch. Backported features increase the minor version.
### Hybrid Distribution[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/release_process.html#hybrid-distribution "Link to this heading")
In very rare situations apps can be shipped **and** distributed via the app store. In those cases it is important to ensure the shipped version is equal or higher than the app store version to prevent a downgrade during the update of Nextcloud.
Hybrid distribution is not recommended.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Content list — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* Content list
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/list.rst)
* * *
Content list[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/list.html#content-list "Link to this heading")
=========================================================================================================================================
Introduction[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/list.html#introduction "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------
On the main content, you may want to have a list of items displayed (like the contacts, or the mail app). We provide a standardized structure for this specific purpose.
Basic layout[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/list.html#basic-layout "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------

Rules and information[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/list.html#rules-and-information "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
* You need to have the following structure for your global content:
HERE YOUR CONTENT LIST
HERE YOUR GLOBAL CONTENT
* The first code/screenshot example show all the combination allowed/available.
* When displaying the checkbox, the star will automatically be hidden.
* The checkboxes are hidden by default. They’re shown when checked or when hover/focus/active
* If you want to show **all** the checkboxes, apply the `selection` class to the `app-content-list`.
* You can **NOT** have more than one button in an entry. You need to create a [popover menu](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html#popovermenu)
if multiple options are needed.
* In case of a popovermenu, see the [popover menu](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/list.html#popovermenulist)
.
* As always, the **JS** is still needed to toggle the `open` class on this menu
* If you use the `app-content-list` standard, the `app-content-details` div will be hidden in mobile mode (full screen). You will need to add the `showdetails` class to the `app-content-list` to show the main content. On mobile view, the whole list/details section (depending on which is shown) will scroll the body.
Popovermenu in item[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/list.html#popovermenu-in-item "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------
If you need a menu inside an item, you need to wrap it with the `icon-more` `div` inside a `app-content-list-menu` div.

☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Talk Integration — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Talk Integration
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/talk.rst)
* * *
Talk Integration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#talk-integration "Link to this heading")
================================================================================================================================================
[Nextcloud Talk](https://apps.nextcloud.com/apps/spreed)
is the chat, video and audio conferencing solution in Nextcloud. Apps can access Talk capabilities through a public API.
All communication from an app to the Talk backend is handled through a _broker_ `\OCP\Talk\IBroker`. [Inject](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
the Talk broker into your class to make use of it.
Check for Talk existence[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#check-for-talk-existence "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Talk is an optional app. It has to be installed and enable to be used.
hasBackend()) {
// Do something with it
} else {
// Hide Talk integration from a user or use other communication channels, if applicable
}
Create a conversation[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#create-a-conversation "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
A new conversation needs a name and at least one moderator. By default this conversation will be private.
createConversation(
'Weekly 1:1',
\[$alice, $bob\]
);
### Customize the conversation[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#customize-the-conversation "Link to this heading")
It’s possible to adjust the defaults.
newConversationOptions();
$conversation \= $broker\->createConversation(
'Weekly 1:1',
\[$alice, $bob\],
$broker\->newConversationOptions()\->setPublic()
);
Delete a conversation[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#delete-a-conversation "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
A conversation can be deleted by id (token).
deleteConversation('abc123');
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Files Metadata — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Files Metadata
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/files-metadata.rst)
* * *
Files Metadata[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#files-metadata "Link to this heading")
======================================================================================================================================================
Added in version 28.
Nextcloud includes an API to manage files’ metadata, with a deep integration in WebDAV.
Concept overview[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#concept-overview "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
When a file is created or modified on Nextcloud, a refresh of its metadata is initiated. You will then be able to listen to the MetadataLiveEvent event to create, update, or delete metadata. If you suspect your process to be hungry in time or resources, you can request for a background event called MetadataBackgroundEvent and do your work there.
Consuming the Files Metadata API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#consuming-the-files-metadata-api "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To consume the Files Metadata API, you will need to [inject](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
`IFilesMetadataManager`. This manager offers the following methods:
> * `refreshMetadata(Node $node, int $process)` This method will initiate the process of refreshing the metadata related to a file.
>
> * `getMetadata(int $fileId, bool $generate)` This method will returns a `IFilesMetadata` which contains metadata related to a file.
>
> * `saveMetadata(IFilesMetadata $filesMetadata)` Save a `IFilesMetadata` and generate indexes.
>
> * `deleteMetadata(int $fileId)` Delete all metadata related to a file.
>
> * `getMetadataQuery(IQueryBuilder $qb, string $fileTableAlias, string $fileIdField)` This method will returns a `IMetadataQuery` to help building Sql request.
>
> * `getKnownMetadata()` Returns a list of known metadata keys globally available to the instance, and the expected type for each value.
>
> * `initMetadata(string $key, string $type, bool $indexed, bool $remotelyEditable)` This method allow to initiate a metadata before any of the files is examined
>
Live & Background Events[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#live-background-events "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Two (2) events can be caught by your app to generate metadata. The first one is called on the main process, just after the upload/modification of the file. The second one is called on a background process, initiated by cronjob.
> * `OCP\FilesMetadata\Event\MetadataLiveEvent`
>
> * `OCP\FilesMetadata\Event\MetadataBackgroundEvent`
>
Both events contain those methods:
> * `getNode()` Returns related `Node`.
>
> * `getMetadata()` Returns `IFilesMetadata`. Any changes made to this object will be saved at the end of the event.
>
Generating metadata from a file might require a lot of resources; in that case it is advised to run this generation on a background job by requesting a re-run by calling the method `MetadataLiveEvent::requestBackgroundJob()`
registerEventListener(MetadataLiveEvent::class, UpdateFilesMetadata::class); $context\->registerEventListener(MetadataBackgroundEvent::class, UpdateFilesMetadata::class); }
public function boot(IBootContext $context): void {
}
}
Note
If the generation of metadata requires low resources, the app only need to listen on `MetadataLiveEvent`
getNode();
// my-first-meta is light enough
$metadata \= $event\->getMetadata();
$metadata\->setString('my-first-meta', 'yes');
if ($event instanceof MetadataLiveEvent) {
$event\->requestBackgroundJob();
return;
}
// my-second-meta is too heavy and should be run on a background job
$metadata\->setInt('my-second-meta', 1234, true);
}
}
Read metadata using occ command[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#read-metadata-using-occ-command "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Stored metadata related to a file can be obtained from a console, using the `occ` command:
$ ./occ metadata:get 1742
{
"my-first-meta": {
"value": "yes",
"type": "string",
"indexed": false
},
"my-second-meta": {
"value": 1234,
"type": "int",
"indexed": true
}
}
Note
The generation process can also be initiated, using the `--refresh` option. Please note that the file owner need to be specified in the command. When refreshing metadata from the console, both `MetadataLiveEvent` and `MetadataBackgroundEvent` are triggered, without waiting for the next tick of crontab
Update metadata using PROPPATCH[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#update-metadata-using-proppatch "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Using WebDAV request, a client can create or update metadata about a file:
curl 'https://cloud.example.net/remote.php/dav/files/test/document.txt' \\
--user test:test \\
--request PROPPATCH \\
--data '
123'
This will return a result like
/remote.php/dav/files/test/document.txtHTTP/1.1 200 OK
Note
WebDAV prefixes metadata with `getServerContainer()\->get(IFilesMetadataManager::class);
$metadataManager\->initMetadata('myapp-test', IMetadataValueWrapper::TYPE\_INT, true, IMetadataValueWrapper::EDIT\_REQ\_OWNERSHIP);
}
Delete metadata using PROPPATCH[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#delete-metadata-using-proppatch "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Using WebDAV request, a client can delete metadata about a file:
curl 'https://cloud.example.net/remote.php/dav/files/test/document.txt' \\
--user test:test \\
--request PROPPATCH \\
--data '
'
Retrieve metadata using PROPFIND[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#retrieve-metadata-using-propfind "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Metadata are available to the WebDAV PROPFIND requests:
curl 'https://cloud.example.net/remote.php/dav/files/test/document.txt' \\
--user test:test \\
--request PROPFIND \\
--data '
'
This will return a result like
/remote.php/dav/files/test/document.txt123HTTP/1.1 200 OK
WebDAV SEARCH based on metadata[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#webdav-search-based-on-metadata "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
curl 'https://cloud.example.net/remote.php/dav/' \\
--user test:test \\
--request SEARCH \\
--data '
/files/test/infinity1010002000'
This will return a result like:
/remote.php/dav/files/test/HTTP/1.1 404 Not Found/remote.php/dav/files/test/document.txt123HTTP/1.1 200 OK/remote.php/dav/files/test/another-one.txt369HTTP/1.1 200 OK
Warning
Metadata used in ORDER and WHERE statement will require metadata to be initiated and set as indexed. It is required to call `IFilesMetadataManager::initMetadata()` before running the WebDAV request or it will returns an exception because of unknown property.
/\*\* lib/AppInfo/Application.php \*/
public function boot(IBootContext $context): void {
/\*\* @var IFilesMetadataManager $metadataManager \*/
$metadataManager \= $context\->getServerContainer()\->get(IFilesMetadataManager::class);
$metadataManager\->initMetadata('my-second-meta', IMetadataValueWrapper::TYPE\_INT, true);
}
Metadata Query Helper[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#metadata-query-helper "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
`IFilesMetadataManager::getMetadataQuery(IQueryBuilder $qb, string $fileTableAlias, string $fileIdField)` returns a `IMetadataQuery` to help building Sql request with the following methods. Parameters when calling the method are the alias of the table, and the name of the field, that contains file ids.
> * `retrieveMetadata()` will add a select on the stored metadata
>
> * `extractMetadata(array $row)` convert a fetched row from the resultinto a `IFilesMetadata`
>
> * `joinIndex(string $metadataKey, bool $enforce)` join the indexes to the request
>
> * `getMetadataKeyField(string $metadataKey)` returns the field and the aliased table of the key of an index
>
> * `getMetadataValueField(string $metadataKey)` returns the field and the aliased table of the value of an index
>
// generate your normal query builder
$qb \= new QueryBuilder();
$qb\->select('file\_id')
\->from('my\_table', 'my\_alias');
/\*\* @var IFilesMetadataManager $metadataManager \*/
$metadataManager \= $context\->getServerContainer()\->get(IFilesMetadataManager::class);
// get a configured query helper and add a select on the metadata
$metadataQuery \= $metadataManager\->getMetadataQuery($qb, 'my\_alias', 'file\_id');
$metadataQuery\->retrieveMetadata();
// right join the index table and get only value lower than 8910 for metadata 'my-second-meta'
$metadataQuery\->joinIndex('my-second-meta', true);
$qb\->where($qb\->expr()\->lt($metadataQuery\->getMetadataValueField('my-second-meta'), $qb\->createNamedParameter(8910)));
// get result
$result \= $qb\->execute();
$items \= $result\->fetchAll();
// extract metadata from each row
$entries \= array\_map(function (array $data) use ($metadataQuery): array {
$data\['metadata'\] \= $metadataQuery\->extractMetadata($data)\->asArray();
}, $items);
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# REST APIs — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* REST APIs
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/rest_apis.rst)
* * *
REST APIs[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#rest-apis "Link to this heading")
=======================================================================================================================================
Offering a RESTful API is not different from creating a [route](https://docs.nextcloud.com/server/latest/developer_manual/basics/routing.html)
and [controllers](https://docs.nextcloud.com/server/latest/developer_manual/basics/controllers.html)
for the web interface. It is recommended though to inherit from ApiController and add `#[CORS]` attribute to the methods so that [web applications will also be able to access the API](https://developer.mozilla.org/en-US/docs/Web/HTTP/Access_control_CORS)
.
'author\_api#preflighted\_cors',
'url' \=> '/api/1.0/{path}',
'verb' \=> 'OPTIONS',
'requirements' \=> array('path' \=> '.+')
)
Keep in mind that multiple apps will likely depend on the API interface once it is published and they will move at different speeds to react to changes implemented in the API. Therefore it is recommended to version the API in the URL to not break existing apps when backwards incompatible changes are introduced:
/index.php/apps/myapp/api/1.0/resource
Modifying the CORS headers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#modifying-the-cors-headers "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
By default the following values will be used for the preflighted OPTIONS request:
* **Access-Control-Allow-Methods**: ‘PUT, POST, GET, DELETE, PATCH’
* **Access-Control-Allow-Headers**: ‘Authorization, Content-Type, Accept’
* **Access-Control-Max-Age**: 1728000
To add an additional method or header or allow less headers, simply pass additional values to the parent constructor:
/` | `/ocs/v2.php/apps//` | `/ocs/v2.php/apps//` |
| Access from web frontend | yes | yes | yes |
| Access from non-browser | partial [\[1\]](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#id3) | yes | yes |
| Access from external website | no | no | yes |
| Encapsulated data | no | yes (JSON or XML) | yes (JSON or XML) |
Methods from `Controller` classes can return `DataResponse` objects similar to `OCSController` class methods. For methods of a `Controller` class, the data of this response is sent e.g. as JSON as you provide it. Basically, the output is very similar to what `json_encode` would do. In contrast, the `OCSController` will encapsulate the data in an outer shell that provides some more (meta) information. For example a status code (similar to the HTTP status code) is transmitted at top level. The actual data is transmitted in the `data` property.
As a rule of thumb one can conclude that OCS provides a good way to handle most use cases including sufficient security checks. The only exception to this is if you want to provide an API for external usage where you have to comply with an externally defined API scheme. Here, the encapsulation introduced in OCS and CSRF checks might be in your way.
### Historical options[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#historical-options "Link to this heading")
Deprecated since version 30: The information in this section are mainly for reference purposes. Do not use the approaches in new code.
Before Nextcloud 30 the plain `Controller` classes’ methods did not respect the `OCS-APIRequest` header. Thus, to provide access to this type of controller methods for external apps, it was necessary to use the `#[NoCSRFRequired]` attribute (or the corresponding `@NoCSRFRequired` annotation).
The following combinations of attributes were relevant for various scenarios:
1. Plain frontend route: `Controller` class
2. Plain frontend with CRSF checks disabled: `Controller` class and `#[NoCSRFRequired]` attribute on the method
3. Plain frontend route with CORS enabled: `Controller` class and `#[CORS]` and `#[NoCSRFRequired]` attributes on the route
4. OCS route: `OCSController` class
5. OCS route with CORS enabled: `OCSController` class and `#[CORS]` attribute on the method
Hint
The two scenarios involving the `OCSController` have not changed and, thus, the state-of-the-art documentation as noted above still holds true. Thus, these options are not reconsidered here again for simplicity reasons and to get the overall view more crisp.
The warnings about not using `NoCSRFRequired` and `CORS` as mentioned in the state-of-the-art section holds true here as well.
| | | | |
| --- | --- | --- | --- |Comparison of different API types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#id5 "Link to this table")
| Description | `Controller` class | `Controller` class with
`NoCSRFRequired` on method | `Controller` class with
`NoCSRFRequired` and `CORS`
on method |
| --- | --- | --- | --- |
| URL prefix (relative to server) | `/apps//` | `/apps//` | `/apps//` |
| Access from web frontend | yes | yes (CSRF risk) | yes (CSRF risk) |
| Access from non-browser | no | yes | yes |
| Access from external website | no | no | yes |
| Encapsulated data | no | no | no |
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Digging deeper — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* Digging deeper
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/index.rst)
* * *
Digging deeper[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html#digging-deeper "Link to this heading")
=============================================================================================================================================
* [API reference](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/api.html)
* [PHP public API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/api.html#php-public-api)
* [`Consumable`, `Listenable` and `Catchable`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/api.html#consumable-listenable-and-catchable)
* [`Implementable`, `Dispatchable` and `Throwable`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/api.html#implementable-dispatchable-and-throwable)
* [PHP unstable API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/api.html#php-unstable-api)
* [Config & Preferences](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/index.html)
* [AppConfig](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/appconfig.html)
* [Concept overview](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/appconfig.html#concept-overview)
* [AppFramework](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/appconfig.html#appframework)
* [Consuming the AppConfig API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/appconfig.html#consuming-the-appconfig-api)
* [UserConfig](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/userconfig.html)
* [Concept overview](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/userconfig.html#concept-overview)
* [Consuming the UserConfig API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/userconfig.html#consuming-the-userconfig-api)
* [Lexicon](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/lexicon.html)
* [Concept overview](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/config/lexicon.html#concept-overview)
* [Classloader](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/classloader.html)
* [Server autoloading](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/classloader.html#server-autoloading)
* [App autoloading](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/classloader.html#app-autoloading)
* [Replacing Nextcloud’s autoloader](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/classloader.html#replacing-nextcloud-s-autoloader)
* [Context Chat](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html)
* [Implementing a content provider for Context Chat](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#implementing-a-content-provider-for-context-chat)
* [The IContentProvider interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#the-icontentprovider-interface)
* [Using the IContentManager service](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#using-the-icontentmanager-service)
* [Implementing the ContentProviderRegisterEvent event](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#implementing-the-contentproviderregisterevent-event)
* [Submitting ContentItem data](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#submitting-contentitem-data)
* [Continuous Integration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/continuous_integration.html)
* [Linting](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/continuous_integration.html#linting)
* [info.xml](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/continuous_integration.html#info-xml)
* [php](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/continuous_integration.html#php)
* [php-cs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/continuous_integration.html#php-cs)
* [Static analysis](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/continuous_integration.html#static-analysis)
* [Dashboard](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html)
* [Register a dashboard widget](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#register-a-dashboard-widget)
* [The IConditionalWidget interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iconditionalwidget-interface)
* [Provide a user interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#provide-a-user-interface)
* [Dashboard API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#dashboard-api)
* [Render dashboard widgets using the API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#render-dashboard-widgets-using-the-api)
* [Providing widgets to clients](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#providing-widgets-to-clients)
* [The IButtonWidget interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-ibuttonwidget-interface)
* [The IIconWidget interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iiconwidget-interface)
* [The IOptionWidget interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-ioptionwidget-interface)
* [The IAPIWidget interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iapiwidget-interface)
* [The IAPIWidgetV2 interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-iapiwidgetv2-interface)
* [The IReloadableWidget interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#the-ireloadablewidget-interface)
* [Use the API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/dashboard.html#use-the-api)
* [Deadlocks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html)
* [Understanding the locking situation](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html#understanding-the-locking-situation)
* [Mitigations](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html#mitigations)
* [Ignoring deadlocks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html#ignoring-deadlocks)
* [Retrying deadlocks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html#retrying-deadlocks)
* [Avoiding deadlocks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html#avoiding-deadlocks)
* [References](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/deadlock.html#references)
* [Debugging](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html)
* [Debug mode](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#debug-mode)
* [Identifying errors](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#identifying-errors)
* [Debugging variables](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#debugging-variables)
* [Using a PHP debugger (XDebug)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#using-a-php-debugger-xdebug)
* [Debugging JavaScript](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#debugging-javascript)
* [Debugging HTML and templates](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#debugging-html-and-templates)
* [Debugging SQL queries](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#debugging-sql-queries)
* [Debugging MariaDB queries](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#debugging-mariadb-queries)
* [Using alternative app directories](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/debugging.html#using-alternative-app-directories)
* [Email](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/email.html)
* [Basic usage](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/email.html#basic-usage)
* [Inline attachments](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/email.html#inline-attachments)
* [Files Metadata](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html)
* [Concept overview](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#concept-overview)
* [Consuming the Files Metadata API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#consuming-the-files-metadata-api)
* [Live & Background Events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#live-background-events)
* [Read metadata using occ command](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#read-metadata-using-occ-command)
* [Update metadata using PROPPATCH](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#update-metadata-using-proppatch)
* [Delete metadata using PROPPATCH](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#delete-metadata-using-proppatch)
* [Retrieve metadata using PROPFIND](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#retrieve-metadata-using-propfind)
* [WebDAV SEARCH based on metadata](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#webdav-search-based-on-metadata)
* [Metadata Query Helper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/files-metadata.html#metadata-query-helper)
* [Groupware integration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/index.html)
* [Calendar integration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar.html)
* [Access calendars and events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar.html#access-calendars-and-events)
* [Create calendar events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar.html#create-calendar-events)
* [Calendar providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar.html#calendar-providers)
* [Resources](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar.html#resources)
* [Rooms](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar.html#rooms)
* [Integration of custom calendar providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar_provider.html)
* [Registering the calendar with the Nextcloud API interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar_provider.html#registering-the-calendar-with-the-nextcloud-api-interface)
* [Legacy access to the Sabre classes](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar_provider.html#legacy-access-to-the-sabre-classes)
* [The calendar object class](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar_provider.html#the-calendar-object-class)
* [The calendar class](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar_provider.html#the-calendar-class)
* [The calendar plugin class](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar_provider.html#the-calendar-plugin-class)
* [Register the calendar provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/calendar_provider.html#register-the-calendar-provider)
* [Contacts Menu](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/contacts_menu.html)
* [Accessing contact info](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/contacts_menu.html#accessing-contact-info)
* [Actions](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/contacts_menu.html#actions)
* [User status](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/contacts_menu.html#user-status)
* [Mail Provider Interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/mail_provider.html)
* [Terminology](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/mail_provider.html#terminology)
* [Consuming a Mail Service](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/mail_provider.html#consuming-a-mail-service)
* [Providing a Mail Service](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/groupware/mail_provider.html#providing-a-mail-service)
* [HTTP Client](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html)
* [Acquiring a HTTP Client](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#acquiring-a-http-client)
* [HEAD request](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#head-request)
* [GET request](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#get-request)
* [POST request](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#post-request)
* [PUT request](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#put-request)
* [DELETE request](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#delete-request)
* [OPTIONS request](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#options-request)
* [Error handling](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/http_client.html#error-handling)
* [JavaScript APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html)
* [npm packages](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#npm-packages)
* [Usage](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#usage)
* [Compatibility](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#compatibility)
* [Development](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#development)
* [Packages in detail](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#packages-in-detail)
* [`@nextcloud/auth`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-auth)
* [`@nextcloud/axios`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-axios)
* [`@nextcloud/event-bus`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-event-bus)
* [`@nextcloud/dialogs`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-dialogs)
* [`@nextcloud/files`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-files)
* [`@nextcloud/initial-state`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-initial-state)
* [`@nextcloud/l10n`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-l10n)
* [`@nextcloud/logger`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-logger)
* [`@nextcloud/moment`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-moment)
* [`@nextcloud/password-confirmation`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-password-confirmation)
* [`@nextcloud/paths`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-paths)
* [`@nextcloud/router`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-router)
* [`@nextcloud/sharing`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-sharing)
* [`@nextcloud/vue`](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#nextcloud-vue)
* [Events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#events)
* [Network state changes](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#network-state-changes)
* [Global variables](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#global-variables)
* [OC – internal APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#oc-internal-apis)
* [OCA – App APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#oca-app-apis)
* [OCP – Public APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/javascript-apis.html#ocp-public-apis)
* [Machine Translation](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/machinetranslation.html)
* [Consuming the Translation API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/machinetranslation.html#consuming-the-translation-api)
* [Implementing a Translation provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/machinetranslation.html#implementing-a-translation-provider)
* [Provider with user context](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/machinetranslation.html#provider-with-user-context)
* [Providing language detection](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/machinetranslation.html#providing-language-detection)
* [Provider registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/machinetranslation.html#provider-registration)
* [Nextcloud Flow](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/flow.html)
* [Entities](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/flow.html#entities)
* [Operations](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/flow.html#operations)
* [Configuration Component](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/flow.html#configuration-component)
* [NPM](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html)
* [npm build](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html#npm-build)
* [npm run dev, npm run watch](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html#npm-run-dev-npm-run-watch)
* [npm test](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html#npm-test)
* [npm run lint (optional)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/npm.html#npm-run-lint-optional)
* [Notifications](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/notifications.html)
* [OpenID Connect (Oidc)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/oidc.html)
* [Getting the login token](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/oidc.html#getting-the-login-token)
* [Token exchange](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/oidc.html#token-exchange)
* [Generating a token if Nextcloud is the provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/oidc.html#generating-a-token-if-nextcloud-is-the-provider)
* [Out-of-office periods](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/out_of_office.html)
* [Access data from within a Nextcloud App via OCP](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/out_of_office.html#access-data-from-within-a-nextcloud-app-via-ocp)
* [Listening to events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/out_of_office.html#listening-to-events)
* [Common data structure](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/out_of_office.html#common-data-structure)
* [Open Metrics exporter](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/openmetrics.html)
* [Register a new exporter](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/openmetrics.html#register-a-new-exporter)
* [Implement a new exporter](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/openmetrics.html#implement-a-new-exporter)
* [Performance considerations](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html)
* [PHP Performance](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#php-performance)
* [Database performance](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#database-performance)
* [Writing scalable transactions](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#writing-scalable-transactions)
* [Measuring performance](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#measuring-performance)
* [Cached data](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#cached-data)
* [Getting help](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/performance.html#getting-help)
* [Phone number util](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/phonenumberutil.html)
* [Convert input into standard format](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/phonenumberutil.html#convert-input-into-standard-format)
* [Get the country code for a region](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/phonenumberutil.html#get-the-country-code-for-a-region)
* [PSR](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html)
* [PSR-0: Autoloading](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-0-autoloading)
* [PSR-3: Logger Interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-3-logger-interface)
* [PSR-4: Autoloading](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-4-autoloading)
* [PSR-11: Container Interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-11-container-interface)
* [PSR-20: Clock](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/psr.html#psr-20-clock)
* [Profile](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profile.html)
* [Register a profile action](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profile.html#register-a-profile-action)
* [Profiler](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html)
* [Get the app](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#get-the-app)
* [Enable the app](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#enable-the-app)
* [Disable the app](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#disable-the-app)
* [Using the app](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#using-the-app)
* [The General Request and Response View](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#the-general-request-and-response-view)
* [The Database Queries View](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#the-database-queries-view)
* [The LDAP View](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#the-ldap-view)
* [The Event View](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#the-event-view)
* [The Cache View](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#the-cache-view)
* [Contributing](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/profiler.html#contributing)
* [Projects](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/projects.html)
* [Register a resource provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/projects.html#register-a-resource-provider)
* [Provide a user interface](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/projects.html#provide-a-user-interface)
* [Public Pages](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html)
* [Concept](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html#concept)
* [Implementing an API called from a public share page](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html#implementing-an-api-called-from-a-public-share-page)
* [Implementing an authenticated public page](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html#implementing-an-authenticated-public-page)
* [Reference providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html)
* [Display link previews](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#display-link-previews)
* [NcRichText](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncrichtext)
* [NcReferenceWidget](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncreferencewidget)
* [API to resolve links](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#api-to-resolve-links)
* [Render link previews in clients](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#render-link-previews-in-clients)
* [Use the Smart Picker in your app](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#use-the-smart-picker-in-your-app)
* [NcRichContenteditable](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncrichcontenteditable)
* [NcReferencePickerModal](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncreferencepickermodal)
* [getLinkWithPicker](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#getlinkwithpicker)
* [Use the Smart Picker in clients](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#use-the-smart-picker-in-clients)
* [Get the provider list](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#get-the-provider-list)
* [Use the Unified Search API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#use-the-unified-search-api)
* [Update a provider last usage date](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#update-a-provider-last-usage-date)
* [Register a reference provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#register-a-reference-provider)
* [Extend link preview support](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#extend-link-preview-support)
* [Match links](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#match-links)
* [Resolving links](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#resolving-links)
* [Interactive widgets](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#interactive-widgets)
* [Provide generic data for clients](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#provide-generic-data-for-clients)
* [Extend the Smart Picker](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#extend-the-smart-picker)
* [Declare supported Unified Search providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#declare-supported-unified-search-providers)
* [Register a custom picker component](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#register-a-custom-picker-component)
* [Repair steps](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/repair.html)
* [Creating a repair step](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/repair.html#creating-a-repair-step)
* [Outputting information](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/repair.html#outputting-information)
* [Register a repair-step](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/repair.html#register-a-repair-step)
* [Repair-step types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/repair.html#repair-step-types)
* [REST APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html)
* [Modifying the CORS headers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#modifying-the-cors-headers)
* [Relation of REST and OCS](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#relation-of-rest-and-ocs)
* [State-of-the-Art methods and comparison](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#state-of-the-art-methods-and-comparison)
* [Historical options](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#historical-options)
* [Search](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html)
* [Concept overview](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#concept-overview)
* [Fetching provider IDs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#fetching-provider-ids)
* [Fetching individual search results](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#fetching-individual-search-results)
* [Simple search providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#simple-search-providers)
* [Advanced search provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#advanced-search-provider)
* [External search provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#external-search-provider)
* [Provider registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#provider-registration)
* [Handling search requests](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#handling-search-requests)
* [Pagination](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#pagination)
* [Optional attributes](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#optional-attributes)
* [Declare in-app search](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#declare-in-app-search)
* [Privacy](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#privacy)
* [Security](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/security.html)
* [Rate Limiting](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/security.html#rate-limiting)
* [Remote Host Validation](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/security.html#remote-host-validation)
* [Trusted domain](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/security.html#trusted-domain)
* [Settings](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html)
* [Declarative settings](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html)
* [Registering settings schema](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#registering-settings-schema)
* [Class-based schema registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#class-based-schema-registration)
* [Event-based schema registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#event-based-schema-registration)
* [Handling settings storage](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#handling-settings-storage)
* [Schema field types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#schema-field-types)
* [Settings form](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html#settings-form)
* [Section](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html#section)
* [Registering Settings and Sections](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html#registering-settings-and-sections)
* [Setup checks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html)
* [Register a setup check](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html#register-a-setup-check)
* [Define a setup check](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html#define-a-setup-check)
* [Running HTTP requests against the server](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html#running-http-requests-against-the-server)
* [Snowflake IDs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html)
* [Store a Snowflake ID in database](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html#store-a-snowflake-id-in-database)
* [Generate a Snowflake ID](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html#generate-a-snowflake-id)
* [Decode a Snowflake ID](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html#decode-a-snowflake-id)
* [Speech-To-Text](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html)
* [Consuming the Speech-To-Text API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#consuming-the-speech-to-text-api)
* [Listening to the transcription events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#listening-to-the-transcription-events)
* [Implementing a Speech-To-Text provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#implementing-a-speech-to-text-provider)
* [Provider with user context](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#provider-with-user-context)
* [Provider registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#provider-registration)
* [Talk Integration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html)
* [Check for Talk existence](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#check-for-talk-existence)
* [Create a conversation](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#create-a-conversation)
* [Customize the conversation](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#customize-the-conversation)
* [Delete a conversation](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/talk.html#delete-a-conversation)
* [Task Processing](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html)
* [Consuming the Task Processing API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#consuming-the-task-processing-api)
* [Tasks types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#tasks-types)
* [Tasks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#tasks)
* [Task statuses](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#task-statuses)
* [Listening to the task processing events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#listening-to-the-task-processing-events)
* [Implementing a TaskProcessing provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#implementing-a-taskprocessing-provider)
* [Providing additional inputs and outputs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#providing-additional-inputs-and-outputs)
* [Providing input defaults](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#providing-input-defaults)
* [Working with Enum shape types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#working-with-enum-shape-types)
* [Providing more task types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#providing-more-task-types)
* [Triggerable providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#triggerable-providers)
* [Provider and task type registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#provider-and-task-type-registration)
* [Text Processing](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html)
* [Consuming the Text Processing API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#consuming-the-text-processing-api)
* [Tasks types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#tasks-types)
* [Tasks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#tasks)
* [Task statuses](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#task-statuses)
* [Listening to the text processing events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#listening-to-the-text-processing-events)
* [Implementing a TextProcessing provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#implementing-a-textprocessing-provider)
* [Processing tasks in the context of a user](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#processing-tasks-in-the-context-of-a-user)
* [Streamlining processing for fast providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#streamlining-processing-for-fast-providers)
* [Providing more task types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#providing-more-task-types)
* [Provider registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#provider-registration)
* [Text-To-Image](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html)
* [Consuming the Text-To-Image API](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#consuming-the-text-to-image-api)
* [Tasks](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#tasks)
* [Task statuses](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#task-statuses)
* [Listening to the image generation events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#listening-to-the-image-generation-events)
* [Implementing a Text-To-Image provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#implementing-a-text-to-image-provider)
* [Provider registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#provider-registration)
* [Two-factor providers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html)
* [Implementing a simple two-factor auth provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#implementing-a-simple-two-factor-auth-provider)
* [Register the provider state](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#register-the-provider-state)
* [Registering a two-factor auth provider](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#registering-a-two-factor-auth-provider)
* [Providing an icon (optional)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#providing-an-icon-optional)
* [Provide personal settings (optional)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#provide-personal-settings-optional)
* [Make a provider activatable by the admin (optional)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#make-a-provider-activatable-by-the-admin-optional)
* [Make a provider deactivatable by the admin (optional)](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#make-a-provider-deactivatable-by-the-admin-optional)
* [User Status](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/status.html)
* [Query Status](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/status.html#query-status)
* [Updating the status programmatically](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/status.html#updating-the-status-programmatically)
* [User migration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/user_migration.html)
* [Register a migrator](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/user_migration.html#register-a-migrator)
* [User management](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html)
* [Creating users](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#creating-users)
* [Modifying users](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#modifying-users)
* [User session information](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#user-session-information)
* [User objects](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#user-objects)
* [User managers](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#user-managers)
* [Web Host Metadata](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html)
* [Writing a handler](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#writing-a-handler)
* [Example generic handler](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#example-generic-handler)
* [Example webfinger handler](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#example-webfinger-handler)
* [Handler registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#handler-registration)
* [WebDAV collection preload events](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html)
* [Overview](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#overview)
* [When the event is emitted](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#when-the-event-is-emitted)
* [Subscribing to the event in a plugin](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#subscribing-to-the-event-in-a-plugin)
* [Built-in examples](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#built-in-examples)
* [Best practices](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#best-practices)
* [Working with time](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/time.html)
* [Methods](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/time.html#methods)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Setup checks — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Setup checks
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/setup_checks.rst)
* * *
Setup checks[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html#setup-checks "Link to this heading")
================================================================================================================================================
Setup checks allow to test specific functionality of the server and report issues with configuration early to the administrators to prevent run time issues.
One example for setup checks is the JavaScript Modules test that ensures the server is able to serve `.mjs` files correctly, which is needed for apps that use modern JavaScript for their UI. Any issue with the configuration would be reported to the administrator, either on the web interface (admin setting), or when running the `occ setupchecks` command, before a user experience the issue.
Register a setup check[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html#register-a-setup-check "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Setup checks are registered within the registration context of the app bootstrap:
registerSetupCheck(JavaScriptModules::class);
}
// ...
}
Define a setup check[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html#define-a-setup-check "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Defining a custom setup check is done by simply implementing `OCP\SetupCheck\SetupResult`, for this example we will create a check that ensures the Nextcloud instance is not running in debug mode.
l10n\->t('Debug mode');
}
public function getCategory(): string {
return 'system';
}
public function run(): SetupResult {
if ($this\->config\->getSystemValueBool('debug', false)) {
return SetupResult::warning($this\->l10n\->t('This instance is running in debug mode. Only enable this for local development and not in production environments.'));
} else {
return SetupResult::success($this\->l10n\->t('Debug mode is disabled.'));
}
}
}
First it is required to provide a name, the name which should summarize the check and should be provided as a user visible, thus translated string.
public function getName(): string {
// This is user visible and thus should be translated
return $this\->l10n\->t('Debug mode');
}
Setup checks are grouped by category, the category should be one of
* `security`: Related to the security of the instance
* `accounts`: Related to user accounts
* `system`: System status Related
* Custom category: Will be merged into system. Examples for existing custom categories are `network` and `database`.
public function getCategory(): string {
return 'system';
}
The most important part is the `run` function. This function should perform the test and report the result as a `OCP\SetupCheck\SetupResult`. Available severity level are:
* `SetupResult::success`: Test succeeded no action needed.
* `SetupResult::info`: No action required but it can not be guaranteed that the check passed (e.g. missing precondition for running the test).
* `SetupResult::warning`: The test failed but the result is not fatal, yet the administrator should be warned about this.
* `SetupResult::error`: The test failed and some functionality is not available or might be broken.
It is also possible to add a link to documentation to ease administrators solving the issue. The link is simply passed as the second parameter to the `SetupResult`.
Additionally it is also possible to use rich objects (`OCP\RichObjectStrings`) for formatting the message, in this case the third parameter should contain the rich object parameters.
Note
Please be aware that setup checks could be ran from both, the web frontend and from the CLI. Meaning they might use different `php.ini` files.
public function run(): SetupResult {
if ($this\->config\->getSystemValueBool('debug', false)) {
return SetupResult::warning($this\->l10n\->t('This instance is running in debug mode. Only enable this for local development and not in production environments.'));
} else {
return SetupResult::success($this\->l10n\->t('Debug mode is disabled.'));
}
}
### Running HTTP requests against the server[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/setup_checks.html#running-http-requests-against-the-server "Link to this heading")
As mentioned in the initial example it is sometimes needed to run HTTP requests for a setup check, to ensure configuration is working correctly. To ease writing tests like that we provide the `CheckServerResponseTrait` trait.
The `run` function of the JavaScript modules setup check could look like:
public function run(): SetupResult {
// This is a real existing file
$testFile \= $this\->urlGenerator\->linkTo('settings', 'js/esm-test.mjs');
$noResponse \= true;
foreach ($this\->runRequest('HEAD', $testFile) as $response) {
$noResponse \= false;
if (preg\_match('/(text|application)\\/javascript/i', $response\->getHeader('Content-Type'))) {
return SetupResult::success();
}
}
if ($noResponse) {
return SetupResult::warning($this\->l10n\->t('Unable to run check for JavaScript support.') . "\\n" . $this\->serverConfigHelp());
}
return SetupResult::error($this\->l10n\->t('Your webserver does not serve \`.mjs\` files using the JavaScript MIME type. This will break some apps by preventing browsers from executing the JavaScript files.'));
}
The `runRequest` is provided by the `CheckServerResponseTrait`, it accepts a HTTP request method as the first parameter (in this example `HEAD`) and an URL with an absolute path, so meaning the full path but no host set, like provided when using the URL generator. One example string would be `nextcloud/apps/settings/js/esm-test.mjs`. Internally the function requests that URL on all possible URLs (using the current host, the trusted domains and the cli overwrite URL), and then yields a result for each request.
`CheckServerResponseTrait::serverConfigHelp` provides information about common pitfalls that prevent HTTP requests against the current server. If no response is yielded from the `runRequest` method then this information should be included.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Public Pages — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Public Pages
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/publicpage.rst)
* * *
Public Pages[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html#public-pages "Link to this heading")
==============================================================================================================================================
A lot of apps in Nextcloud want to expose public pages in some form. This can be to share files, a calendar or anything else. To ensure all those pages benefit from the security enhancements we add simplified controllers were created for app developers to use.
Concept[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html#concept "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------
A public page is there to display a resource that a user wants to expose via a public link in an app.
A public page is identified by some `token` and can be protected by a `password`.
If a public page is password protected by default we will show the normal authentication page to enter the password.
A public page can also call other endpoints. These endpoints operate very similarly with the difference that if the user is not properly authenticated it will throw a 404.
It is required that you have a parameter (probably in your url) with the `token`. As an example your `routes.php` could look like:
\[\
\[ 'name' \=> 'PublicAPI#get', 'url' \=> '/api/{token}', 'verb' \=> 'GET' \],\
\[ 'name' \=> 'PublicDisplay#get', 'url' \=> '/display/{token}', 'verb' \=> 'GET' \],\
\]\
\];
Implementing an API called from a public share page[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html#implementing-an-api-called-from-a-public-share-page "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
As said the PublicShareController is a very basic controller. You need to implement 3 functions. `isPasswordProtected`, `isValidToken` and `getPasswordHash`.
getToken() \=== 'secretToken';
}
/\*\*
\* Allows you to specify if this share is password protected
\*/
protected function isPasswordProtected(): bool {
return true;
}
/\*\*
\* Your normal controller function. The following annotation will allow guests
\* to open the page as well
\*/
#\[PublicPage\]
public function get() {
// Work your magic
}
}
You can also chose to overwrite the `shareNotFound` function. That is called when the token is not valid. You can do additional logging here for example.
Implementing an authenticated public page[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/publicpage.html#implementing-an-authenticated-public-page "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
On some pages password authentication might be required (just like the when you share a file via public link with a password). In this case you need to extend a different provider.
The AuthPublicShareController requires in addition to the PublicShareController that you also implement the `verifyPassword` and `showShare` functions.
Additionally you can overwrite the `showAuthenticate` and `showAuthFailed` functions if you do not want to use the default authentication pages.
The `authFailed` and `authSucceeded` functions can be overwritten as well and are called depending on the if authentication passed or not. You can handle additional logging there for example.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# App upgrade guide — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/index.html)
* App upgrade guide
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.rst)
* * *
App upgrade guide[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html#app-upgrade-guide "Link to this heading")
=================================================================================================================================================================================
Once you’ve created and published the first version of your app, you will want to keep it up to date with the latest Nextcloud features.
These sub pages will cover the most important changes in Nextcloud, as well as some guides on how to upgrade existing apps.
* [Upgrade to Nextcloud 34](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_34.html)
* [Upgrade to Nextcloud 33](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_33.html)
* [Upgrade to Nextcloud 32](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_32.html)
* [Upgrade to Nextcloud 31](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.html)
* [Upgrade to Nextcloud 30](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_30.html)
* [Upgrade to Nextcloud 29](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_29.html)
* [Upgrade to Nextcloud 28](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_28.html)
* [Upgrade to Nextcloud 27](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_27.html)
* [Upgrade to Nextcloud 26](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_26.html)
* [Upgrade to Nextcloud 25](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_25.html)
* [Upgrade to Nextcloud 24](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_24.html)
* [Upgrade to Nextcloud 23](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_23.html)
* [Upgrade to Nextcloud 22](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_22.html)
* [Upgrade to Nextcloud 21](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_21.html)
* [Upgrade to Nextcloud 20](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_20.html)
* [Upgrade to Nextcloud 19](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_19.html)
* [Upgrade to Nextcloud 18](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_18.html)
* [Upgrade to Nextcloud 17](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_17.html)
* [Upgrade to Nextcloud 16](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_16.html)
* [Upgrade to Nextcloud 15](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_15.html)
* [Upgrade to Nextcloud 14](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_14.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Main content — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* Main content
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/content.rst)
* * *
Main content[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/content.html#main-content "Link to this heading")
============================================================================================================================================
Since 14, we standardized our structure.
Your application will be directly injected into the `#content` div.
Rules and information[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/content.html#rules-and-information "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------
* You cannot nor need to modify the header or the outside elements of your application.
* The whole body needs to scroll to be compatible with the mobile views. Therefore the sidebar and the app-navigation are fixed/sticky.
* Unless your application does not require a scrollable area, do not use any overflow properties on the parents of your content.
* The `app-navigation-toggle` is automatically injected. The navigation hide/show is automatically managed.
* Do not use `#content-wrapper` anymore
* If your app is injecting itself by replacing the #content element, make sure to keep the `#content` id
* If you use the `app-content-list` standard, the `app-content-details` div will be hidden in mobile mode (full screen). You will need to add the `showdetails` class to the `app-content-list` to show the main content. On mobile view, the whole list/details section (depending on which is shown) will scroll the body
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# HTML elements — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* HTML elements
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/html.rst)
* * *
HTML elements[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/html.html#html-elements "Link to this heading")
===========================================================================================================================================
Progress bar[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/html.html#progress-bar "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------
Nextcloud support and provides an already themed progress bar.
Please use the html5 `progress` element.

Checkboxes and radios[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/html.html#checkboxes-and-radios "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
As default html5 checkboxes & radios are **not** customizable, we created an override using label and `::after` elements.
There are 2 colors:
* Default themed with the primary color.
* White colored.
Requirements:
* You need to have a `label` element **directly** after the `input` element.
* The input **must** have the `checkbox` or `radio` class.
* To use the white theme, you **need** to also add the `checkbox--white` or `radio--white` class.
* Your label **must** have an associated text for accessibility.

Buttons[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/html.html#buttons "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Icons — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* Icons
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/icons.rst)
* * *
Icons[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/icons.html#icons "Link to this heading")
============================================================================================================================
List of available icons[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/icons.html#list-of-available-icons "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Deprecated since version 25.
The icons available in the core/img/ folder of the server are deprecated. You can use them at own risk. Due to a change of the way the list is produced now on the server it can no longer be automatically turned into documentation.
Please use [Material design icons](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/icons.html#material-design-icons)
instead.
Svg color api[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/icons.html#svg-color-api "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------
Deprecated since version 25.
The svg API is not supported anymore due to performance reasons.
Please use [Material design icons](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/icons.html#material-design-icons)
instead.
Material design icons[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/icons.html#material-design-icons "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
If you need more than the shipped default icons, using the material-design-icons would be a good idea. For usage with vuejs look over here: [https://nextcloud-vue-components.netlify.app/#/Components/NcIconSvgWrapper](https://nextcloud-vue-components.netlify.app/#/Components/NcIconSvgWrapper)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Text-To-Image — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Text-To-Image
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/text2image.rst)
* * *
Text-To-Image[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#text-to-image "Link to this heading")
================================================================================================================================================
Added in version 28.
Deprecated since version 30: Use the TaskProcessing API instead
Nextcloud offers a **Text-To-Image** API. The overall idea is that there is a central OCP API that apps can use to prompt tasks to latent diffusion AI models and similar image generation tools. To be technology agnostic any app can provide this functionality by registering a Text-To-Image provider.
Consuming the Text-To-Image API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#consuming-the-text-to-image-api "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To consume the Text-To-Image API, you will need to [inject](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
`\OCP\TextToImage\IManager`. This manager offers the following methods:
> * `hasProviders()` This method returns a boolean which indicates if any providers have been registered. If this is false you cannot use the image generation feature.
>
> * `runTask(Task $task)` This method provides the actual functionality. The task is defined using the Task class. This method runs the task synchronously, so depending on the implementation it is uncertain how long it will take (between 3s and several hours).
>
> * `scheduleTask(Task $task)` This method also runs a task, but asynchronously in a background job. The task is defined using the Task class.
>
> * `runOrScheduleTask(Task $task)` This method also runs a task, but fist checks the expected runtime of the provider to be used. If the runtime fits inside the available processing time for the current request the task is run synchronously, otherwise it is scheduled as a background job. The task is defined using the Task class.
>
> * `getTask(int $id)` This method fetches a task specified by its id.
>
> * `getUserTask(int $id, ?string $userId)` This method fetches a task specified by its id and the user that is associated with it.
>
> * `getUserTasksByApp(?string $userId, string $appId, ?string $identifier = null)` This method fetches tasks by a user created by a specific app (optionally, you can also specify the task identifier as an additional filter)
>
If you would like to use the image generation functionality in a client, there are also OCS endpoints available for this: [OCS Text-To-Image API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html#ocs-text2image-api)
### Tasks[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#tasks "Link to this heading")
To create a task we use the `\OCP\TextToImage\Task` class. Its constructor takes the following arguments: `new \OCP\TextToImage\Task(string $input, string $appId, int $numberOfImages, ?string $userId, string $identifier = '')`. For example:
$text2imageTask \= new Task($documentTitle, "my\_app", 8, $userId, (string) $documentId);
The task class objects have the following methods available:
> * `getStatus()` This method returns one of the below statuses.
>
> * `getId()` This method will return `null` before the task has been passed to `runTask` or `scheduleTask`, otherwise it will return an integer
>
> * `getInput()` This returns the input string.
>
> * `getAppId()` This returns the originating application ID of the task.
>
> * `getNumberOfImages()` This returns the number of generated images for the task.
>
> * `getIdentifier()` This returns the original scheduler-defined identifier for the task
>
> * `getUserId()` This returns the originating user ID of the task.
>
> * `getOutputImages()` This method will return `null` unless the task is successful, if its, it will return a list of `IImage` objects
>
You could run the task directly as follows. However, this will block the current PHP process until the task is done, which can sometimes take dozens of minutes, depending on which provider is used.
try {
$text2imageManager\->runTask($text2imageTask);
} catch (\\OCP\\PreConditionNotMetException|\\OCP\\TextToImage\\Exception\\TaskFailureException $e) {
// task failed
// return error
}
// task was successful
The wiser choice, when you are in the context of a HTTP controller, is to schedule the task for execution in a background job, as follows:
try {
$text2imageManager\->scheduleTask($text2imageTask);
} catch (\\OCP\\PreConditionNotMetException|\\OCP\\DB\\Exception $e) {
// scheduling task failed
}
// task was scheduled successfully
Of course, you might want to schedule the task in a background job **only** if it takes longer than the request timeout. This is what runOrScheduleTask does.
try {
$text2imageManager\->runOrScheduleTask($text2imageTask);
} catch (\\OCP\\PreConditionNotMetException|\\OCP\\DB\\Exception $e) {
// scheduling task failed
// return error
} catch (\\OCP\\TextToImage\\Exception\\TaskFailureException $e) {
// task was run but failed
// status will be STATUS\_FAILED
// return error
}
switch ($text2imageTask\->getStatus()) {
case \\OCP\\TextToImage\\Task::STATUS\_SUCCESSFUL:
// task was run directly and was successful
case \\OCP\\TextToImage\\Task::STATUS\_RUNNING:
case \\OCP\\TextToImage\\Task::STATUS\_SCHEDULED:
// task was deferred to background job
default:
// something went wrong
}
### Task statuses[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#task-statuses "Link to this heading")
All tasks always have one of the below statuses:
Task::STATUS\_FAILED \= 4;
Task::STATUS\_SUCCESSFUL \= 3;
Task::STATUS\_RUNNING \= 2;
Task::STATUS\_SCHEDULED \= 1;
Task::STATUS\_UNKNOWN \= 0;
### Listening to the image generation events[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#listening-to-the-image-generation-events "Link to this heading")
Since `scheduleTask` does not block, you will need to listen to the following events in your app to obtain the resulting images or be notified of any failure.
> * `OCP\TextToImage\Events\TaskSuccessfulEvent` This event class offers the `getTask()` method which returns the up-to-date task object, with the output from the model.
>
> * `OCP\TextToImage\Events\TaskFailedEvent` In addition to the `getTask()` method, this event class provides the `getErrorMessage()` method which returns the error message as a string (only in English and for debugging purposes, so don’t show this to the user)
>
For example, in your `lib/AppInfo/Application.php` file:
$context\->registerEventListener(OCP\\TextToImage\\Events\\TaskSuccessfulEvent::class, ImageGenerationResultListener::class);
$context\->registerEventListener(OCP\\TextToImage\\Events\\TaskFailedEvent::class, ImageGenerationResultListener::class);
The corresponding `ImageGenerationResultListener` class could look like the following:
getTask()\->getAppId() !== Application::APP\_ID) {
return;
}
if ($event instanceof TaskSuccessfulEvent) {
$images \= $event\->getTask()\->getOutputImages()
// store $images somewhere
}
if ($event instanceof TaskFailedEvent) {
$error \= $event\->getErrorMessage()
$userId \= $event\->getTask()\->getUserId()
// Notify relevant user about failure
}
}
}
Implementing a Text-To-Image provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#implementing-a-text-to-image-provider "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A **Text-To-Image provider** is a class that implements the interface `OCP\TextToImage\IProvider`.
l\->t('My awesome text to image provider');
}
public function generate(string $input, array $resources): void {
// write the resulting images to the file resources in $resources
}
}
The method `getId` returns a string to uniquely identify the registered provider. You can use the class name for this for example.
The method `getName` returns a string to identify the registered provider in the user interface and should be localized.
The method `generate` implements the image generation step. It gets passed an array of `resource` values. The length of the array indicates how many images should be generated. Each image should be written to one of the resources, e.g. using `fwrite()`. In case execution fails for some reason, you should throw a `RuntimeException` with an explanatory error message.
The class would typically be saved into a file in `lib/TextToImage` of your app but you are free to put it elsewhere as long as it’s loadable by Nextcloud’s [dependency injection container](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
.
Provider registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#provider-registration "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
The provider class is registered via the [bootstrap mechanism](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
of the `Application` class.
registerTextToImageProvider(ImageGenerationProvider::class); }
public function boot(IBootContext $context): void {}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Search — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Search
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/search.rst)
* * *
Search[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#search "Link to this heading")
==============================================================================================================================
Nextcloud 20 offers a new **unified search**. The overall idea is to have one combined view for search, but have results of any data source displayed there. Hence this is logic is built on a pluggable architecture where apps register their search providers.
Concept overview[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#concept-overview "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
The unified search combines a variable number of search providers into a unified search result for the user. To improve the user experience with search, the search results should be displayed quickly. Therefore parallelism is used to split the process into several requests that can be processed concurrently, to give the client (e.g. JavaScript in the browser) the ability to display partial search results as they come on.
Hence the search process consists of two steps.
> 1. Fetch the current set of search provider IDs
>
> 2. Fetch each provider’s search results
>
These two steps have to be run consecutively, but the individual requests in the second step can be dispatched and processed concurrently.
### Fetching provider IDs[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#fetching-provider-ids "Link to this heading")
`GET https://cloud.domain/ocs/v2.php/search/providers`
This will return a structure like
{
"ocs": {
"meta": {
"…": "…"
},
"data": \[\
{\
"id": "talk-message",\
"appId": "spreed",\
"name": "Messages",\
"icon": "/apps/spreed/img/app.svg",\
"order": \-2,\
"triggers": \["talk-message"\],\
"filters": {\
"term": "string",\
"since": "datetime",\
"until": "datetime",\
"person": "person"\
},\
"inAppSearch": false\
},\
{\
"id": "files",\
"appId": "files",\
"name": "Fichiers",\
"icon": "/apps/files/img/app.svg",\
"order": 5,\
"triggers": \["files"\],\
"filters": {\
"term": "string",\
"since": "datetime",\
"until": "datetime",\
"person": "person",\
"min-size": "int",\
"max-size": "int",\
"mime": "string",\
"type": "string"\
},\
"inAppSearch": false\
}\
\]
}
}
`filters` list filters supported by the provider with their expected type
### Fetching individual search results[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#fetching-individual-search-results "Link to this heading")
`GET https://cloud.domain/ocs/v2.php/search/providers/files/search?term=cat`
{
"ocs": {
"meta": {
"…": "…"
},
"data": {
"name": "Files",
"isPaginated": false,
"entries": \[\
{\
"thumbnailUrl": "/core/preview?x=32&y=32&fileId=9261",\
"title": "my cute cats.jpg",\
"subline": "/my cute cats.jpg",\
"resourceUrl": "/apps/files/?dir=/&scrollto=my%20cute%20cats.jpg"\
},\
{\
"thumbnailUrl": "/core/preview?x=32&y=32&fileId=1553",\
"title": "cat (2).png",\
"subline": "/cat (2).png",\
"resourceUrl": "/apps/files/?dir=/&scrollto=cat%20%282%29.png"\
}\
\],
"cursor": null
}
}
}
Simple search providers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#simple-search-providers "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
A **search provider** is a class which implements the interface `\OCP\Search\IProvider`.
l\->t('My custom group');
}
public function getOrder(string $route, array $routeParameters): int {
if (str\_contains($route, Application::APP\_ID)) {
// Active app, prefer my results
return \-1;
}
return 55;
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
return SearchResult::complete(
'My custom group', // TODO: this should be translated
\[\
...\
\]
);
}
}
The method `getId` returns a string identifier of the registered provider. It has to be globally unique, hence must not conflict with any other apps. Therefore it’s advised to use just the app ID (e.g. `mail`) as ID or an ID that is prefixed with the app id, like `mail_recipients`. `getName` is a translated name for your search results.
The `getOrder` method returns the order of the provider for the current page. With the route parameter you can check if the route is from your app and in that case use a negative value. Otherwise your app should use a value around 50.
The method `search` transforms a search request into a search result.
The class would typically be saved into a file in `lib/Search` of your app but you are free to put it elsewhere as long as it’s loadable by Nextcloud’s [dependency injection container](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
.
Advanced search provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#advanced-search-provider "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Since Nextcloud 28.0, it is possible to use advanced search providers by implementing `\OCP\Search\IFilteringProvider`. This interface allows to supports other filtering types.
getFilter('since')?->get();
/\*\* @var $user ?IUser \*/
$user \= $query\->getFilter('custom\_user')?->get();
// TODO Do actual search
return new SearchResult(/\* … \*/);
}
}
`getSupportedFilters` lists the filters supported by the provider. If filters send by client are not supported, the provider will not receive the request.
`getCustomFilters` allows to declare specific filters. In current state, the specific filters will only be available in the API.
External search provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#external-search-provider "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Since Nextcloud 32, to improve privacy, you can extend your provider with the `\OCP\Search\IExternalProvider` interface and implement the `isExternalProvider()` method to indicate that the search is performed on external (3rd-party) resources. In the Unified Search UI, searching through these providers is disabled by default (via toggle switch).
Provider registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#provider-registration "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
The provider class is registered via the [bootstrap mechanism](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
of the `Application` class.
registerSearchProvider(Provider::class);
}
public function boot(IBootContext $context): void {}
}
Handling search requests[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#handling-search-requests "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Search requests are processed in the `search` method. The `$user` object is the user who the result shall be generated for. `$query` gives context information like the **search term**, the **sort order**, the **route information**, the **size limit** of a request and the **cursor** for follow-up request of paginated results.
The result is encapsulated in the `SearchResult` class that offers two static factory methods `complete` and `paginated`. Both of these methods take an array of `SearchResultEntry` objects.
Next, you’ll see a dummy provider that returns a static set of results.
l10n \= $l10n;
$this\->urlGenerator \= $urlGenerator;
}
public function getId(): string {
return 'mysearchprovider';
}
public function getName(): string {
return $this\->l\->t('My app');
}
public function getOrder(string $route, array $routeParameters): int {
if (strpos($route, Application::APP\_ID . '.') \=== 0) {
// Active app, prefer my results
return \-1;
}
return 25;
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
return SearchResult::complete(
$this\->l10n\->t('My app'),
\[\
new SearchResultEntry(\
$this\->urlGenerator\->linkToRoute(\
'myapp.Preview.getPreviewByFileId',\
\[\
'id' \=> 1\
\]\
),\
'Search result 1',\
'This goes into the subline',\
$this\->urlGenerator\->linkToRoute(\
'myapp.view.index',\
\[\
'id' \=> 1,\
\]\
)\
)\
\]
);
}
}
Each of the result entry has
* A thumbnail or icon that is a (relative) URL
* A title, e.g. the name of a file
* A subline, e.g. the path to a file
* A resource URL that makes it possible to navigate to the details of this result
* Optional icon CSS class that is applied then the thumbnail URL was not set
* A boolean rounded, whether the thumbnail should be rounded, e.g. when it’s an avatar
Apps **may** return the full result in `search`, but in most cases the size of the result set can become too big to fit into one HTTP request and is complicated to display to the user, hence the set should be split into chunks – it should be **paginated**.
### Pagination[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#pagination "Link to this heading")
Paginated results work almost like complete results. The differences are that the `SearchResult::paginated` factory method is used to build the set and that you need a **cursor** for this.
There are two ways to use the **cursor**: offset-based pagination and cursor-based pagination.
For **offset-based pagination** you return `$query->getLimit()` results and specify this number as **cursor**. Any subsequent call where `$query->getCursor()` does not return `null` you take the value as **offset** for the next page. The following example shall demonstrate this use case.
l10n \= $l10n;
$this\->urlGenerator \= $urlGenerator;
}
public function getId(): string {
return 'mysearchprovider';
}
public function getName(): string {
return $this\->l\->t('My app');
}
public function getOrder(string $route, array $routeParameters): int {
if (strpos($route, Application::APP\_ID . '.') \=== 0) {
// Active app, prefer my results
return \-1;
}
return 25;
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
$offset \= ($query\->getCursor() ?? 0);
$limit \= $query\->getLimit();
$data \= \[\]; // Fill this with $limit entries, where the first entry is row $offset
return SearchResult::paginated(
$this\->l10n\->t('My app'),
$data,
$offset + $limit
);
}
}
So the first call will get a cursor of `null` and a limit of, say, 20. So the first 20 rows are fetched. The next call will have a cursor of 20, so the 20st to 39th rows are fetched.
The downside of a offset-based pagination is that when the underlying data changes (new entries are inserted into or deleted from the database, files change), the offset might be out of sync from on request to its successor. Therefore, if possible, a true cursor-based pagination is preferable.
For a **cursor-based pagination** a app-specific property is used to know a reference to the last element of the previous search request. The presumption of this algorithm is that the result set is sorted by an attribute and this attribute is an `int` or `string`. The attribute value of the last element in the result page determines the cursor for the next search request. Again, a small example shall demonstrate how this works.
l10n \= $l10n;
$this\->urlGenerator \= $urlGenerator;
}
public function getId(): string {
return 'mysearchprovider';
}
public function getName(): string {
return $this\->l\->t('My app');
}
public function getOrder(string $route, array $routeParameters): int {
if (strpos($route, Application::APP\_ID . '.') \=== 0) {
// Active app, prefer my results
return \-1;
}
return 25;
}
public function search(IUser $user, ISearchQuery $query): SearchResult {
$cursor \= $query\->getCursor();
$limit \= $query\->getLimit();
if ($cursor \=== null) {
$data \= \[\]; // Fill this with $limit entries sorted ascending by created\_at
} else {
$data \= \[\]; // Fill this with $limit entries sorted ascending by created\_at that have a created\_at > $cursor
}
$last \= end($data);
return SearchResult::paginated(
$this\->l10n\->t('My app'),
$data,
$last\->getCreatedAt()
);
}
}
### Optional attributes[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#optional-attributes "Link to this heading")
The unified search is available via OCS, which means client application like the mobile apps can use it to get access to the server search mechanism. The default properties of a search result entry might be difficult to parse and interpret in those clients, hence it’s possible to add optional string attributes to each entry.
addAttribute("type", "deckCard");
$entry\->addAttribute("cardId", "1234");
$entry\->addAttribute("boardId", "567");
Note
This method was added in Nextcloud 21. If your app also targets Nextcloud 20 you should either not use it or add a version check to invoke the method only conditionally.
Declare in-app search[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#declare-in-app-search "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
If your application also have in-app search (like `mail` or `talk`), your provider can also implements interface `\OCP\Search\IInAppSearch`.
This will add a link for it after search results.
Privacy[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#privacy "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------
All search providers have to value privacy and prevent leaking of sensitive data by default. Therefore search terms must not be sent to third parties by default. If a search provider makes use of third party services, user consent has to be acquired, e.g. by an opt-in toggle in the user’s personal settings.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Popover menu — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* Popover menu
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/popovermenu.rst)
* * *
Popover menu[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html#popover-menu "Link to this heading")
================================================================================================================================================
What is a popover menu[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html#what-is-a-popover-menu "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
This is a quick menu that open on click. For menus, we use the three-dot-icon.
This is exactly the same as the [navigation menu](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#navigation-menu)
. The only difference is the popovermenu class.
Basic layout[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html#basic-layout "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------

Technical details[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html#technical-details "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
* The only allowed menu items elements are **a**, **button** and **span** for the checkbox and radio only.
* You can mix between a and button on the same menu (in case of form or direct link) like the example above
* You need to put the entire menu just after the three dot icon `
...
`
* You do not need JS, CSS only is ok for positioning. JS is **still** required to handle the hide/show.
* Only **one** ul is allowed.
* Only **one level** of menu is allowed.
* Every entry **needs** to have its own icon. This greatly improves the UX.
* The required **right** distance to the border (or padding, whatever you want to use) of the three-dot icon should be 14px (5 for menu margin and 6 for arrow position)
* The `span` element **must** have the `menuitem` class.
* The checkbox/radio must use the [nextcloud custom](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/html.html#checkboxes-and-radios)
* The form element is optional if you’re using inputs.
* Supported inputs are all text based ones and buttons type ones

Alignment[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html#alignment "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------
If you want to align your menu, you can add the class to the main popovermenu div.
* Center: `menu-center`
* Left: `menu-left`
* Right is by default
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Introduction — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* Introduction
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/navigation.rst)
* * *
Introduction[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#introduction "Link to this heading")
===============================================================================================================================================
The navigation section of any Nextcloud app is the left sidebar. It is basically composed of
* a primary action button
* a menu
* a settings area
The primary action button and the settings area are optional.
New button[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#new-button "Link to this heading")
===========================================================================================================================================
Introduction[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#id1 "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------
A primary action button is just a stylised button located above the navigation part of your app. The goal is to have an homogeneity of design across all apps using this button.
Basic layout[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#basic-layout "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------

Rules[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#rules "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------
* Stay simple, don’t use overcomplicated text in this button.
* Avoid using sentences longer than one line.
* Do not edit the styling of this button.
* Only **one** button is allowed here.
App navigation menu[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#app-navigation-menu "Link to this heading")
=============================================================================================================================================================
Introduction[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#id2 "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------
The main navigation menu represents the main navigation of your app.
It needs to be:
* Organised
* Simple
* Responsive
Nextcloud provides a very organized way of building menus. We implemented various essential functions and provide easy way of using them.
Basic layout[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#id3 "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------

Basic rules[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#basic-rules "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------
* You can **not** change the default padding of the navigation elements.
* We encourage you to add icons on every top-level item of your navigation for accessibility.
* Do **not** override the default structure and/or CSS. Everything has been carefully tuned.
Utils: menu, counter & buttons[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#utils-menu-counter-buttons "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Each entry is allowed to have a counter and/or a button for user interaction.
* The `app-navigation-entry-utils` snippet need to be placed right next to the main link of your entry.
* Maximum **two** items are allowed into the utils section. You can have:
* Two [buttons](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#navigation-buttons)
* One [button](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#navigation-buttons)
and one [button](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#navigation-counter)
* You **can’t** have more than two buttons, if you need more, you need to add a menu.
* The order of the button and the counter are **not** interchangeable. You need to put the counter before the menu.
1
### Menu[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#menu "Link to this heading")
If you need to add a few interactions for your entry, you can put everything in a popover menu. The menu needs to be placed after the `app-navigation-entry-utils`.
For the global rules and/or layout, you can check the dedicated [popover menu section](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/popovermenu.html#popovermenu)
.

The menu is hidden by default and has to be triggered by adding the `open` class to the `app-navigation-entry-menu` div. In case of AngularJS the following small directive can be added to handle all the display and click logic out of the box:
app.run(function ($document, $rootScope) {
'use strict';
$document.click(function (event) {
$rootScope.$broadcast('documentClicked', event);
});
});
app.directive('appNavigationEntryUtils', function () {
'use strict';
return {
restrict: 'C',
link: function (scope, elm) {
var menu \= elm.siblings('.app-navigation-entry-menu');
var button \= $(elm)
.find('.app-navigation-entry-utils-menu-button button');
button.click(function () {
menu.toggleClass('open');
});
scope.$on('documentClicked', function (scope, event) {
if (event.target !== button\[0\]) {
menu.removeClass('open');
}
});
}
};
});
### Counter[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#counter "Link to this heading")
If you need to add a counter to your menu entry, you can simply use this structure. Do not change the alignment of the text. If you’re using

1
The counter should be limited to 999 and turn to 999+ if any higher number is given. If AngularJS is used the following filter can be used to get the correct behavior:
app.filter('counterFormatter', function () {
'use strict';
return function (count) {
if (count \> 999) {
return '999+';
}
return count;
};
});
Use it like this:
{{ count | counterFormatter }}
#### Highlighted counter[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#highlighted-counter "Link to this heading")
The counter can also be highlighted to attract some focus, e.g. for unread chat messages

99+
### Buttons[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#buttons "Link to this heading")
The same way we display the menu three-dot-icon button, you’re allowed to use up to 2 buttons in a single entry.
* The icon class goes directly on the `button` element.
* If no class is set, the three-dot-icon will be used by default

Drag and drop[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#drag-and-drop "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------
The class which should be applied to a first level element **li** that hosts or can host a second level is **drag-and-drop**. This will cause the hovered entry to slide down giving a visual hint that it can accept the dragged element. In case of jQuery UI’s droppable feature, the **hoverClass** option should be set to the **drag-and-drop** class.
Collapsible entry[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#collapsible-entry "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------
By default, all sub-entries are shown. This behavior can be changed by creating a collapsible menu. This way, the menu will be hidden and an arrow will be added in in front of it (replacing the icon if any).
The opening of the menu is activated and animated by the class `open` on the main `li`.
* You can **not** have a collapsible menu on a sub-item, this can only exist on a top-level element.
* You can set the open class by default if you want.
* Do **not** use the collapsible menu if your element does not have sub-items.
* You **still** need to use JS to handle the click event.
Important
* If your top-level link is only used as a header, the **entire** `a` needs to be used to toggle the `open` class.
* If your top-level link is used to redirect the user or to trigger something else, you **need** to add the collapsible button and use it as the `open` class toggle trigger.

Entry bullet[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#entry-bullet "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
Every entry can have a colored marker in front of it. We call it a bullet.
* You can **not** combine an icon with a bullet.
* You need to use the CSS to define the bullet color.

Undo entry[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#undo-entry "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------
* Undo entries can be used on any level you want.
* When an entry is deleted, please use the usual **7 seconds delay feedback** before final deletion.
* Please use the sentence _Deleted XXXX_ as the feedback message.
* You need to use the `deleted` class to trigger the animated hide/show of the undo entry.

Edit entry[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#edit-entry "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------
* Editable entries can be used on any level you want.
* You can replace the `form` by a `div` if you wish to do your request with JS.
* You need to use the `editing` class to trigger the animated hide/show of the input.
* You’re allowed to use only one submit input. It **must** be the validation button.
* The input **must** have the same value as the entry link text.

Pinned entry[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#pinned-entry "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
Every top-level entry can be pinned at the bottom.
* All the pinned entries can be mixed between non-pinned entries.
* All the pinned entries **must** have the `pinned` class.
* The **first** pinned entry **must** also have the `first-pinned` class.

Various information[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#various-information "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
* You can add the `icon-loading-small` class to any `li` element to set it in a loading state.
* Every element as a `min-height` of 44px as that is the minimum recommended touch target. It also helps with clickability and separation on desktop environments.
Settings[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#settings "Link to this heading")
=======================================================================================================================================
Introduction[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#id4 "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------
To create a settings area create a div with the id `app-settings` inside the `app-navigation` div.
* The data attribute `data-apps-slide-toggle` slides up a target area using a jQuery selector and hides the area if the user clicks outside of it.
* Max height of the settings area is 300px. Do **not** change that.
* Keep it clear, organized and simple.
Basic layout[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/navigation.html#id5 "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------

☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# CSS — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/index.html)
* CSS
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/css.rst)
* * *
CSS[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#css "Link to this heading")
======================================================================================================================
While the recommended way to develop the user interface is using Vue with the Nextcloud provided components, Nextcloud also provides CSS variables and classes to style components to have a consistent look.
CSS variables[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#css-variables "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------
It is strongly recommended to use the Nextcloud provided CSS variables for styling components. This way you can be sure that the theming and accessibility app can dynamically adjust the values. Doing so also allows users to enforce dark or light theme, high contrast or other theming related options.
### Primary color variables[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#primary-color-variables "Link to this heading")
The primary color is the main accent color that can be configured by the administrator or the user (if user theming is enabled).
| Variable | Example | Usage |
| --- | --- | --- |
| `--color-primary` | `#00679e` | Primary color configured by user |
| `--color-primary-text` | `#ffffff` | Text color to be used on `--color-primary` |
| `--color-primary-hover` | `#3285b1` | Variant of `--color-primary` for hover effects |
| `--color-primary-light` | `#e5eff5` | Light variant of `--color-primary` used for secondary actions |
| `--color-primary-light-text` | `#00293f` | Text color to be used on `--color-primary-light` |
| `--color-primary-light-hover` | `#dbe4ea` | Variant of `--color-primary-light` for hover effects |
| `--color-primary-element` | `#00679e` | Accessibility adjusted variant of `--color-primary` to be used on interactive elements |
| `--color-primary-element-text` | `#ffffff` | Text color to be used on `--color-primary-element` |
| `--color-primary-element-text-dark` | `#f5f5f5` | Less contrast version of `--color-primary-element-text` |
| `--color-primary-element-hover` | `#005a8a` | Variant of `--color-primary-element` for hover effects |
| `--color-primary-element-light` | `#e5eff5` | Light variant of `--color-primary-element` used for secondary actions |
| `--color-primary-element-light-text` | `#00293f` | Text color to be used on `--color-primary-element-light` |
| `--color-primary-element-light-hover` | `#dbe4ea` | Variant of `--color-primary-element-light` for hover effects |
| `--primary-invert-if-bright` | `invert(100%)` | Filter to invert icons placed on primary color backgrounds if the primary color is bright |
| `--primary-invert-if-dark` | `invert(100%)` | Filter to invert icons placed on primary color backgrounds if the primary color is dark |
### Background variables[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#background-variables "Link to this heading")
| Variable | Example | Usage |
| --- | --- | --- |
| `--color-background-plain` | `#00679e` | The background color of the `body` element |
| `--color-background-plain-text` | `#ffffff` | Text color to be used directly on the background (e.g. header menu) |
| `--image-background` | `url('clouds.jpg')` | Background image used on the `body` element (optional) |
| `--background-image-invert-if-bright` | `invert(100%)` | Filter to invert (bright) icons placed directly on the body background (app menu) |
### General color variables[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#general-color-variables "Link to this heading")
| Variable | Example | Usage |
| --- | --- | --- |
| `--color-main-text` | `#222222` | Main text color |
| `--color-text-maxcontrast` | `#6b6b6b` | Brighter text color that still fulfills accessibility requirements |
| `--color-text-maxcontrast-background-blur` | `#595959` | `--color-text-maxcontrast` for blurred background, see `--color-main-background-blur` |
| `--color-main-background` | `#fffff` | Main background color |
| `--color-main-background-rgb` | `255,255,255` | RGB variant of `--color-main-background` |
| `--color-main-background-blur` | `rgba(var(--color-main-background-rgb), .8)` | Background color used for blurred background, see `--filter-background-blur` |
| `--color-background-hover` | `#f5f5f5` | Background color for hover effects |
| `--color-background-dark` | `#ededed` | Can be used e.g. to colorize selected table rows |
| `--color-background-darker` | `#dbdbdb` | Should only be used for elements, not as a text background! Otherwise it will not work for accessibility. |
| `--color-border` | `#ededed` | Default element border color |
| `--color-border-dark` | `#dbdbdb` | Darker version of the border color |
| `--color-border-maxcontrast` | `#7d7d7d` | Brightest possible border color for accessibility |
| `--color-placeholder-light` | `#e6e6e6` | Color for input placeholders |
| `--color-placeholder-dark` | `#cccccc` | Darker version of `--color-placeholder-light` |
| `--color-scrollbar` | `#33333344` | Color for scrollbars |
| `--color-loading-light` | `#cccccc` | Color for the loading spinner (the bright part of it) |
| `--color-loading-dark` | `#444444` | Color for the loading spinner (the dark part of it) |
| `--color-box-shadow-rgb` | `77,77,77` | Color for box shadow effects in RGB notation |
| `--color-box-shadow` | `rgba(var(--color-box-shadow-rgb), 0.5)` | Color for box shadow effects |
| `--background-invert-if-dark` | `invert(100%)` | Filter to invert (dark) icons (e.g. set if the color theme is dark) |
| `--background-invert-if-bright` | `invert(100%)` | Filter to invert (bright) icons (e.g. set if the color theme is bright) |
### State colors variables[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#state-colors-variables "Link to this heading")
| Variable | Example | Usage |
| --- | --- | --- |
| `--color-text-error` | `#c90000` | For text on **normal** background that should have an error state |
| `--color-text-success` | `#099f05` | For text on **normal** background that should have an success state |
| `--color-element-error` | `#c90000` | Color with proper contrast for elements which have an error state for example icons |
| `--color-element-info` | `#0077C7` | Color with proper contrast for elements which have an info state for example icons |
| `--color-element-success` | `#099f05` | Color with proper contrast for elements which have an success state for example icons |
| `--color-element-warning` | `#BF7900` | Color with proper contrast for elements which have an warning state for example icons |
| `--color-border-error` | `#c90000` | Border color for elements which have an error state like inputs with failing validity |
| `--color-border-success` | `#099f05` | Border color for elements which have a success state like inputs which have been saved |
| `--color-favorite` | `#a37200` | Color to mark favorites, can be used to color e.g. a star icon for favorites |
| `--color-error` | `#FFE7E7` | Color to show error state, this should not be used for text but for element backgrounds |
| `--color-error-hover` | `#ffc3c3` | Background color for hover effects of `--color-error` |
| `--color-error-text` | `#8A0000` | Text color on elements using `--color-error` as background |
| `--color-warning` | `#FFEEC5` | Color to show warning state, this should not be used for text but for element backgrounds |
| `--color-warning-hover` | `#ffe4a1` | Background color for hover effects of `--color-warning` |
| `--color-warning-text` | `#664700` | Text color on elements using `--color-warning` as background |
| `--color-success` | `#D8F3DA` | Color to show success state, this should not be used for text but for element backgrounds |
| `--color-success-hover` | `#bdebc0` | Background color for hover effects of `--color-success` |
| `--color-success-text` | `#005416` | Text color on elements using `--color-success` as background |
| `--color-info` | `#D5F1FA` | Color to show info state, this should not be used for text but for element backgrounds |
| `--color-info-hover` | `#b5e6f6` | Background color for hover effects of `--color-info` |
| `--color-info-text` | `#0066AC` | Text color on elements using `--color-info` as background |
| `--color-error-rgb` | `219,6,6` | (⚠️ deprecated since 32.0.0) RGB variant of `--color-error` |
| `--color-info-rgb` | `0,113,173` | (⚠️ deprecated since 32.0.0) RGB variant of `--color-info` |
| `--color-success-rgb` | `45,123,65` | (⚠️ deprecated since 32.0.0) RGB variant of `--color-success` |
| `--color-warning-rgb` | `163,114,0` | (⚠️ deprecated since 32.0.0) RGB variant of `--color-warning` |
### Element structure variables[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#element-structure-variables "Link to this heading")
| Variable | Example | Usage |
| --- | --- | --- |
| `--animation-quick` | `100ms` | Animation time for snappy CSS transitions |
| `--animation-slow` | `300ms` | Animation time for more complex transitions |
| `--breakpoint-mobile` | `1024px` | Breakpoint for mobile responsive layout (e.g. if app navigation should be always visible) |
| `--filter-background-blur` | `blur(25px)` | Filter to be used on elements with background blur (e.g. app navigation) |
| `--font-face` | `system-ui, 'Segoe UI', Roboto, Oxygen-Sans` | Font used for Nextcloud user interface |
| `--default-font-size` | `15px` | Font size for normal text |
| `--default-line-height` | `1.5` | Line height for normal text |
| `--default-grid-baseline` | `4px` | Foundation of all spacing sizes used on Nextcloud which are multiples of the baseline size |
| `--border-width-input` | `1px` | Border width for interactive elements such as text fields and selects |
| `--border-width-input-focused` | `2px` | Border width for interactive elements when focussed (adjusted for accessibility) |
| `--border-radius-small` | `4px` | Border radius used for smaller elements |
| `--border-radius-element` | `8px` | Border radius of interactive elements such as buttons, input, navigation and list items. |
| `--border-radius-container` | `12px` | For smaller containers like action menus. |
| `--border-radius-container-large` | `16px` | For larger containers like body or modals. |
| `--default-clickable-area` | `34px` | Default size (width and height) for interactive elements like buttons |
| `--clickable-area-large` | `48px` | Larger size for the main UI elements |
| `--clickable-area-small` | `24px` | Smallest possible size of interactive elements, used by tertiary actions like filter chips |
| `--body-container-radius` | `calc(var(--default-grid-baseline) * 3)` | Border radius of the body container |
| `--body-container-margin` | `calc(var(--default-grid-baseline) * 2)` | Margin of the body container |
| `--header-height` | `50px` | Height of the main app navigation bar |
| `--navigation-width` | `300px` | Width of the in-app navigation sidebar |
| `--sidebar-min-width` | `300px` | Minimum width of the app sidebar on small screens |
| `--sidebar-max-width` | `500px` | Maximum width of the app sidebar on wide screens |
CSS classes[](https://docs.nextcloud.com/server/latest/developer_manual/html_css_design/css.html#css-classes "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------
There are some predefined classes for public use to ease developing an application for Nextcloud.
| CSS class | Usage |
| --- | --- |
| `.hidden-visually` | Hides an element visually from the page but keeps it in the accessibility tree |
| `.hidden` | Hides an element completely from the page (also removed from the accessibility tree) |
| `.bold` | Make content of the element bold emphasize |
| `.center` | Center align the elements text |
| `.clear-left` | Clear float left |
| `.clear-right` | Clear float right |
| `.clear-both` | Clear float on both |
| `.pull-left` | Float left |
| `.pull-right` | Float right |
| `.inlineblock` | Make an element an inline block |
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# User migration — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* User migration
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/user_migration.rst)
* * *
User migration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/user_migration.html#user-migration "Link to this heading")
======================================================================================================================================================
The [User migration app](https://apps.nextcloud.com/apps/user_migration)
may be installed to allow migration of user data.
App developers can integrate into User migration and provide ways to export and import the app data of a user.
Register a migrator[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/user_migration.html#register-a-migrator "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
A migrator is represented by a class implementing the `OCP\\UserMigration\\IMigrator` interface. This class is instantiated whenever a user export or import begins.
myAppManager \= $myAppManager;
$this\->l10n \= $l10n;
}
/\*\*
\* Returns an estimate of the exported data size in KiB.
\* Should be fast, favor performance over accuracy.
\*
\* @since 25.0.0
\* @since 27.0.0 return value may overflow from int to float
\*/
public function getEstimatedExportSize(IUser $user): int|float {
$size \= 100; // 100KiB for user data JSON
return $size;
}
/\*\*
\* Export user data
\*
\* @throws UserMigrationException
\* @since 24.0.0
\*/
public function export(IUser $user, IExportDestination $exportDestination, OutputInterface $output): void {
$output\->writeln('Exporting myapp information in ' . MyAppMigrator::PATH\_MYAPP\_FILE . '…');
try {
$data \= $this\->myAppManager\->getUserData($user);
$exportDestination\->addFileContents(MyAppMigrator::PATH\_MYAPP\_FILE, json\_encode($data));
} catch (Throwable $e) {
throw new UserMigrationException('Could not export myapp information', 0, $e);
}
}
/\*\*
\* Import user data
\*
\* @throws UserMigrationException
\* @since 24.0.0
\*/
public function import(IUser $user, IImportSource $importSource, OutputInterface $output): void {
if ($importSource\->getMigratorVersion($this\->getId()) \=== null) {
$output\->writeln('No version for ' . static::class . ', skipping import…');
return;
}
$output\->writeln('Importing myapp information from ' . MyAppMigrator::PATH\_MYAPP\_FILE . '…');
$data \= json\_decode($importSource\->getFileContents(MyAppMigrator::PATH\_MYAPP\_FILE), true, 512, JSON\_THROW\_ON\_ERROR);
try {
$this\->myAppManager\->setUserData($user, $data);
} catch (Throwable $e) {
throw new UserMigrationException('Could not import myapp information', 0, $e);
}
}
/\*\*
\* Returns the unique ID
\*
\* @since 24.0.0
\*/
public function getId(): string {
return 'myapp';
}
/\*\*
\* Returns the display name
\*
\* @since 24.0.0
\*/
public function getDisplayName(): string {
return $this\->l10n\->t('My App');
}
/\*\*
\* Returns the description
\*
\* @since 24.0.0
\*/
public function getDescription(): string {
return $this\->l10n\->t('My App information');
}
}
The `MyAppMigrator` class needs to be registered during the [app bootstrap](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
.
registerUserMigrator(MyAppMigrator::class);
}
public function boot(IBootContext $context): void {
}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Web Host Metadata — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Web Host Metadata
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/web_host_metadata.rst)
* * *
Web Host Metadata[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#web-host-metadata "Link to this heading")
===============================================================================================================================================================
[RFC6415](https://tools.ietf.org/html/rfc6415)
defines how web hosts can expose their metadata through resources. Starting with Nextcloud 21, it’s possible to register handlers for HTTP requests to the `.well-known/*` route.
Writing a handler[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#writing-a-handler "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
A well known handler is a simple class that implements the `\OCP\Http\WellKnown\IHandler` interface.
'hello'\]),
);
}
}
### Example webfinger handler[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#example-webfinger-handler "Link to this heading")
The following example shows how an app could react to [RFC6415](https://tools.ietf.org/html/rfc6415)
webfinger requests:
urlGenerator \= $urlGenerator;
}
public function handle(string $service, IRequestContext $context, ?IResponse $previousResponse): ?IResponse {
if ($service !== 'webfinger') {
// Not relevant to this handler
return $previousResponse;
}
$subject \= $context\->getHttpRequest()\->getParam('resource', '');
$href \= $this\->urlGenerator\->linkToRouteAbsolute('myapp.example.test');
// Use the previous response and amend it, if possible
$response \= $previousResponse;
if (!($response instanceof JrdResponse)) {
// We override null or any other types
$response \= new JrdResponse($subject);
}
return $response\->addLink('self', 'application/activity+json', $href);
}
}
Handler registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/web_host_metadata.html#handler-registration "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
The handler class is registered via the [bootstrap mechanism](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
of the `Application` class.
registerWellKnownHandler(Handler::class);
}
public function boot(IBootContext $context): void {}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Reference providers — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Reference providers
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/reference.rst)
* * *
Reference providers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#reference-providers "Link to this heading")
===========================================================================================================================================================
Reference providers are related with two Nextcloud features:
* Link previews
* The Smart Picker
Link previews were introduced in Nextcloud 25. Apps can register a reference provider to add preview support for some HTTP links. To provide link previews, a reference provider needs to:
* Resolve the links (get information about the links)
* Render links (show this information in the user interface)
The Smart Picker was introduced in Nextcloud 26. This is a user interface component allowing users to search or generate links from various places in Nextcloud like Text, Talk, Collectives, Notes, Mail… Reference providers can be implemented so they appear in the Smart Picker’s provider list. The Smart Picker can use 2 types of providers:
* the ones to search (using existing Unified Search providers)
* the ones implementing their own custom picker component
In summary, reference providers can be registered by apps to
* add support for new kinds of HTTP links
* resolve the links, get information on the link targets
* optionally provide their own reference widgets to have a custom preview rendering
* extend the Smart Picker
* use existing Unified Search providers
* or optionally register custom picker components to have a specific user interface
This documentation explains how to
* Display link previews in your app
* Use the Smart Picker in your app
* Extend the reference system add preview support for more links
* Extend the Smart Picker with your app’s capabilities
Display link previews[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#display-link-previews "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
If you just want to display links previews in your app without extending the reference system, you need to make sure the `OCP\Collaboration\Reference\RenderReferenceEvent` is dispatched before you load the page where you want to display link previews.
For example, you can place this before returning your TemplateResponse in your controller:
$this\->eventDispatcher\->dispatchTyped(new OCP\\Collaboration\\Reference\\RenderReferenceEvent());
This is done in [Text](https://github.com/nextcloud/text/blob/8a17046aa440df841fe9182205d80ce937068c1a/lib/Listeners/LoadViewerListener.php#L52)
and [Talk](https://github.com/nextcloud/spreed/blob/1f1acbd95943e6184e29de8044cd9d8e775ac7c5/lib/Controller/PageController.php#L280)
if you need more examples.
On the frontend side, there are 3 ways to display link previews (also named reference widgets):
* use the NcRichText Vue component
* use the NcReferenceWidget Vue component
* access the reference API directly and manually render the previews
### NcRichText[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncrichtext "Link to this heading")
Link previews will be automatically rendered for links in the content of the `` Vue component. This component will take care of resolving the links itself.
NcRichText can be imported like this:
import NcRichText from '@nextcloud/vue/dist/Components/NcRichText.js'
[NcRichText component documentation](https://nextcloud-vue-components.netlify.app/#/Components/NcRichText?id=ncrichtext-1)
### NcReferenceWidget[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncreferencewidget "Link to this heading")
You can display a preview for a specific link by using the `` component. You need to ask the server to resolve the link to get a reference object that you can then give as a property to NcReferenceWidget.
To resolve a link:
const myLink \= 'https://github.com'
const requestOptions \= {
params: {
reference: myLink,
},
}
axios.get(generateOcsUrl('references/resolve', 2), requestOptions)
.then((response) \=> {
reference \= response.data.ocs.data.references\[myLink\]
})
Then you can use the reference object you got:
### API to resolve links[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#api-to-resolve-links "Link to this heading")
Accessing the API directly can be useful if you want to:
* resolve links from outside Nextcloud, in a client for example
* manually resolve and render links instead of using the Vue components
Endpoints to resolve links:
* GET /ocs/v2.php/references/resolve (authenticated)
* `reference` parameter with the link to resolve
* GET /ocs/v2.php/references/resolvePublic
* `reference` parameter with the link to resolve
* `sharingToken` parameter with the public share token
* POST /ocs/v2.php/references/resolve
* `references` parameter with an array of links to resolve
* `limit` parameter with the maximum number of links to resolve
* POST /ocs/v2.php/references/resolve
* `references` parameter with an array of links to resolve
* `sharingToken` parameter with the public share token
* `limit` parameter with the maximum number of links to resolve
#### Request examples[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#request-examples "Link to this heading")
curl \-u USER:PASSWD \-H "Accept: application/json" \-H "ocs-apirequest: true" \\
"https://my.nextcloud.org/ocs/v2.php/references/resolve?reference=https://github.com"
will return an OCS response with that data:
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"references": {
"https://github.com": {
"richObjectType": "open-graph",
"richObject": {
"id": "https://github.com",
"name": "GitHub: Let’s build from here",
"description": "GitHub is where over 100 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and fea...",
"thumb": "https://my.nextcloud.org/core/references/preview/3097fca9b1ec8942c4305e550ef1b50a",
"link": "https://github.com"
},
"openGraphObject": {
"id": "https://github.com",
"name": "GitHub: Let’s build from here",
"description": "GitHub is where over 100 million developers shape the future of software, together. Contribute to the open source community, manage your Git repositories, review code like a pro, track bugs and fea...",
"thumb": "https://my.nextcloud.org/core/references/preview/3097fca9b1ec8942c4305e550ef1b50a",
"link": "https://github.com"
},
"accessible": true
}
}
}
}
The link might be supported by a reference provider that also provides more information in a rich object. The generic openGraphObject is still returned. It contains a title, description and image URL if the matching reference provider defined those correctly. For example, resolving `https://www.themoviedb.org/movie/70981` if the `integration_tmdb` app is installed will return:
"data": {
"references": {
"https://www.themoviedb.org/movie/70981": {
"richObjectType": "integration\_tmdb\_movie",
"richObject": {
"adult": false,
"budget": 130000000,
"genres": \[\
{\
"id": 878,\
"name": "Science Fiction"\
},\
{\
"id": 12,\
"name": "Adventure"\
},\
{\
"id": 9648,\
"name": "Mystery"\
}\
\],
"homepage": "https://www.20thcenturystudios.com/movies/prometheus",
"id": 70981,
"imdb\_id": "tt1446714",
"original\_language": "en",
"original\_title": "Prometheus",
"overview": "A team of explorers discover a clue to the origins of mankind on Earth, leading them on a journey to the darkest corners of the universe. There, they must fight a terrifying battle to save the future of the human race.",
"popularity": 68.389,
"release\_date": "2012-05-30",
"revenue": 403354469,
"runtime": 124,
},
"openGraphObject": {
"id": "https://www.themoviedb.org/movie/70981",
"name": "Prometheus",
"description": "30 mai 2012 - A team of explorers discover a clue to the origins of mankind on Earth, leading them on a journey to the darkest corners of the universe. There, they must fight a terrifying battle to save the future of the human race.",
"thumb": "https://my.nextcloud.org/apps/integration\_tmdb/t/p/w500/qsYQflQhOuhDpQ0W2aOcwqgDAeI.jpg?fallbackName=???",
"link": "https://www.themoviedb.org/movie/70981"
},
"accessible": true
}
}
}
### Render link previews in clients[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#render-link-previews-in-clients "Link to this heading")
Clients can choose to support some rich objects types. Developers can follow the rich object formatting recommendations to provide generic information in some cases. The rich object type is not used to predict the data structure. We rather recommend to set rich object attributes respecting a strict format for some common use cases.
More details can be found in [Interactive widgets](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#data-for-clients)
Use the Smart Picker in your app[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#use-the-smart-picker-in-your-app "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are 3 ways to make the Smart Picker appear in your app:
* use the `NcRichContenteditable` component
* use the `NcReferencePickerModal` component
* use the `getLinkWithPicker` helper function
Just like for the link previews, you need to dispatch the `OCP\Collaboration\Reference\RenderReferenceEvent` event before loading the page in which you want to show the Smart Picker.
### NcRichContenteditable[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncrichcontenteditable "Link to this heading")
The Smart Picker is integrated in the NcRichContenteditable Vue component. It is enabled by default but can be disabled by setting the `linkAutocomplete` prop to `false`.
The picker provider list opens when the user types the “/” character. The picker result then gets directly inserted in the content.
[NcRichContenteditable component documentation](https://nextcloud-vue-components.netlify.app/#/Components/NcRichContenteditable)
### NcReferencePickerModal[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#ncreferencepickermodal "Link to this heading")
You display the Smart Picker by using the NcReferencePickerModal Vue component. It is available in the Nextcloud Vue library.
import { NcReferencePickerModal } from '@nextcloud/vue/dist/Components/NcRichText.js'
Available props:
* initialProvider (optional): If a reference provider object is passed, skip the provider selection and directly show this provider
* focusOnCreate (optional, default: true): Focus on the main input element on creation
* isInsideViewer (optional, default: false): Set this to true if NcReferencePickerModal is used inside the Viewer. This tells the Viewer to deal with the focus trap.
### getLinkWithPicker[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#getlinkwithpicker "Link to this heading")
To display the Smart Picker outside Vue, you can use the getLinkWithPicker helper function. It takes 2 parameters:
* providerId (optional, default: null): The provider to select in the picker. If null, the provider selection is displayed first.
* isInsideViewer (optional): This will be passed internally to NcReferencePickerModal as the isInsideViewer prop.
This function returns a promise that resolves with the picker result. This promise is rejected if the user closes the Smart Picker.
import { getLinkWithPicker } from '@nextcloud/vue/dist/Components/NcRichText.js'
getLinkWithPicker(null, true)
.then(result \=> {
console.debug('Smart Picker result', result)
})
.catch(error \=> {
console.error('Smart Picker promise rejected', error)
})
Use the Smart Picker in clients[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#use-the-smart-picker-in-clients "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Clients can partially support the Smart Picker features.
There are 2 types of Smart Picker providers:
* The ones with a custom picker component
* The ones that support one or multiple unified search providers
As the custom picker components are web components, clients might not be able (or want) to render them. So we are mostly interested in the second type here: The ones using unified search providers.
In Nextcloud’s web UI, those providers are rendered with a [generic search Vue component](https://github.com/nextcloud/nextcloud-vue/blob/master/src/components/NcRichText/NcReferencePicker/NcSearch.vue)
which shows a search input, lists the search result in a dropdown menu and directly submits the URL of the selected result. The search is done by directly querying the Unified Search OCS API. This is described later.
To implement something similar to the Smart Picker in a client, it is required to know how to:
* Get the provider list
* Use the Unified Search OCS API
* Update the providers last usage date
### Get the provider list[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#get-the-provider-list "Link to this heading")
The list of Smart Picker providers can be obtained via an OCS endpoint. Each provider object contains the list of supported unified search providers.
Here is the server endpoint to list the smart picker providers:
curl \-u USER:PASSWD \-H "Accept: application/json" \-H "ocs-apirequest: true" \\
"https://my.nextcloud.org/ocs/v2.php/references/providers"
and an example response:
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": \[\
{\
"id": "github-issue-pr",\
"title": "GitHub issues, pull requests and comments",\
"icon\_url": "https://my.nextcloud.org/apps/integration\_github/img/app-dark.svg",\
"order": 10,\
"search\_providers\_ids": \[\
"github-search-issues",\
"github-search-repos"\
\]\
},\
{\
"id": "openstreetmap-point",\
"title": "Map location (by OpenStreetMap)",\
"icon\_url": "https://my.nextcloud.org/apps/integration\_openstreetmap/img/app-dark.svg",\
"order": 10,\
"search\_providers\_ids": \[\
"openstreetmap-search-location"\
\]\
},\
{\
"id": "files",\
"title": "Files",\
"icon\_url": "https://my.nextcloud.org/apps/files/img/folder.svg",\
"order": 0\
}\
\]
}
}
In this example, the “files” Smart Picker provider does not support any unified search provider but the “github-issue-pr” one supports 2 of them and the “openstreetmap-point” support one.
### Use the Unified Search API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#use-the-unified-search-api "Link to this heading")
More details in the [Unified Search](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/search.html#unified-search)
documentation.
Here is how to search using the Unified Search OCS API:
curl \-u USER:PASSWD \-H "Accept: application/json" \-H "ocs-apirequest: true" \\
"https://my.nextcloud.org/ocs/v2.php/search/providers/PROVIDER\_ID/search?term=QUERY&limit=LIMIT"
\# with a cursor (paginated search)
curl \-u USER:PASSWD \-H "Accept: application/json" \-H "ocs-apirequest: true" \\
"https://my.nextcloud.org/ocs/v2.php/search/providers/PROVIDER\_ID/search?term=QUERY&limit=LIMIT&cursor=CURSOR"
\# search a github issue with the query "bug"
curl \-u USER:PASSWD \-H "Accept: application/json" \-H "ocs-apirequest: true" \\
"https://my.nextcloud.org/ocs/v2.php/search/providers/github-search-issues/search?term=bug&limit=2"
Example response:
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"name": "GitHub issues and pull requests",
"isPaginated": true,
"entries": \[\
{\
"thumbnailUrl": "https://my.nextcloud.org/apps/integration\_github/avatar/Daily-DAYO",\
"title": " \[bug\] Change Trim bugs",\
"subline": "⑁ DAYO\_Android#409",\
"resourceUrl": "https://github.com/Daily-DAYO/DAYO\_Android/pull/409",\
"icon": "",\
"rounded": true,\
"attributes": \[\]\
},\
{\
"thumbnailUrl": "https://my.nextcloud.org/apps/integration\_github/avatar/walinejs",\
"title": " \[Bug\]: || \[Bug\]:",\
"subline": "⦿ waline#2014",\
"resourceUrl": "https://github.com/walinejs/waline/issues/2014",\
"icon": "",\
"rounded": true,\
"attributes": \[\]\
}\
\],
"cursor": 2
}
}
}
### Update a provider last usage date[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#update-a-provider-last-usage-date "Link to this heading")
In Nextcloud’s web UI, the order in which the providers are listed to the users depends on the last date they were used. The most recently used providers are displayed first.
In a client, once a provider has been used, a request to this endpoint should be done:
curl \-u USER:PASSWD \-H "Accept: application/json" \-H "ocs-apirequest: true" \-X PUT \\
"https://my.nextcloud.org/ocs/v2.php/search/provider/PROVIDER\_ID"
A `timestamp` optional request parameter can be passed. The last usage date will be set to “now” by default.
Register a reference provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#register-a-reference-provider "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A reference provider is a class implementing the `OCP\Collaboration\Reference\IReferenceProvider` interface. If you just want to resolve links, simply implement the `IReferenceProvider` interface. This is described in the “Resolving links” section.
To support resolving links from public shares, the `OCP\Collaboration\Reference\IPublicReferenceProvider` interface needs to be implemented as well.
If you want your reference provider to be used by the Smart Picker, you need to extend the `OCP\Collaboration\Reference\ADiscoverableReferenceProvider` class to declare all required information.
There are 2 ways to make your provider appear in the smart picker, in other words, 2 types of providers:
* Either your reference provider implements the `OCP\Collaboration\Reference\ISearchableReferenceProvider` interface and you declare a list of unified search providers that will be used by the Smart Picker
* Or you don’t implement this `ISearchableReferenceProvider` interface and make sure you register a custom picker component in the frontend. This is described later in this documentation.
Extend link preview support[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#extend-link-preview-support "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This section is focusing on the methods of the `IReferenceProvider` interface.
Links that are not matched by any reference provider will always be handled by the server’s OpenGraph provider as a fallback. This provider will try to get the information declared in the target page’s meta tag. The link preview will be rendered with the default widget.
For your provider to properly handle some links, you need to implement the `matchReference` and `resolve` methods of `IReferenceProvider`.
In order to resolve links from a public share, `resolvePublic` from `IPublicReferenceProvider` has to be implemented additionally.
### Match links[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#match-links "Link to this heading")
The `matchReference` method of `IReferenceProvider` tells the reference manager if a provider supports a link or not.
public function matchReference(string $referenceText): bool {
// support all URLs starting with https://my.website.org/
return str\_starts\_with($referenceText, 'https://my.website.org/');
}
### Resolving links[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#resolving-links "Link to this heading")
The `resolve` method of `IReferenceProvider` is used to get information about a link and return it as a `OCP\Collaboration\Reference\Reference` object.
Respectively the `resolvePublic` method of `IPublicReferenceProvider` is used to get information about a link from a public share (available since Nextcloud 30).
#### Using the default widget[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#using-the-default-widget "Link to this heading")
If you are fine with the default widget rendering (image on the left, text and subtext on the right), then you just need to provide a title, a description and optionally an image.
public function resolveReference(string $referenceText): ?IReference {
if ($this\->matchReference($referenceText)) {
$title \= $this\->myAwesomeService\->getLinkTitle($referenceText);
$description \= $this\->myAwesomeService\->getLinkDescription($referenceText);
$imageUrl \= $this\->myAwesomeService\->getImageUrl($referenceText);
$reference \= new Reference($referenceText);
$reference\->setTitle($title);
$reference\->setDescription($description);
$reference\->setImageUrl($imageUrl);
return $reference;
}
return null;
}
public function resolveReferencePublic(string $referenceText, string $shareToken): ?IReference {
if ($this\->checkShareToken() \=== $shareToken) {
return $this\->resolveReference($referenceText);
}
return null;
}
#### Using custom reference widgets[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#using-custom-reference-widgets "Link to this heading")
You can customize the rendering of the links you support with your provider.
On the provider side, you need to pass all the information needed by your custom reference widget component by setting the “rich object” of the `Reference` object returned by the `resolve` method.
It is recommended to still set the title, description and image URL on the reference object in case it is used by a client or in a context where the custom reference widgets can’t be used. This way we make sure any generic rendering of link previews still shows some information.
public function resolveReference(string $referenceText): ?IReference {
if ($this\->matchReference($referenceText)) {
$title \= $this\->myAwesomeService\->getLinkTitle($referenceText);
$description \= $this\->myAwesomeService\->getLinkDescription($referenceText);
$imageUrl \= $this\->myAwesomeService\->getImageUrl($referenceText);
$extraInformation \= $this\->myAwesomeService\->getExtraInformation($referenceText);
$reference \= new Reference($referenceText);
$reference\->setTitle($title);
$reference\->setDescription($description);
$reference\->setImageUrl($imageUrl);
$reference\->setRichObject(
'my\_rich\_object\_type',
\[\
'title' \=> $title,\
'description' \=> $description,\
'image\_url' \=> $imageUrl,\
'extra\_info' \=> $extraInformation,\
\]
);
return $reference;
}
return null;
}
public function resolveReferencePublic(string $referenceText, string $shareToken): ?IReference {
if ($this\->checkShareToken() \=== $shareToken) {
return $this\->resolveReference($referenceText);
}
return null;
}
On the frontend side you need to implement and register your custom component. Here is a component example:
You need to react to the `OCP\Collaboration\Reference\RenderReferenceEvent` event to inject a script that will actually register the widget component when needed. For example, in your `lib/AppInfo/Application.php` file:
$context\->registerEventListener(OCP\\Collaboration\\Reference\\RenderReferenceEvent::class, MyReferenceListener::class);
The corresponding `MyReferenceListener` class can look like:
{
const Widget \= Vue.extend(MyCustomWidgetComponent)
new Widget({
propsData: {
richObjectType,
richObject,
accessible,
},
}).$mount(el)
})
And last but not least, the MyCustomWidgetComponent Vue component in which you can render the link preview in a custom fashion:
{{ richObject.title }}
{{ richObject.extra\_info }}
### Interactive widgets[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#interactive-widgets "Link to this heading")
If you want to provide a custom widget that is interactive you can use the `interactive` attribute that is passed along the `registerWidget` function.
Apps will determine if they can render the interactive widget or not.
When writing a custom widget make sure properly handle different restrictions to ensure that the widget is usable in any integrating app.
* The width of the widget should be flexible and not exceed the width of the parent element.
* The height can be flexible but might be limited by the parent element, so ensure that the widget can be scrolled if necessary
* Your script will be loaded on every page that uses widget rendering so make sure to keep the script size as small as possible and use lazy loading for any additional resources
import { registerCustomPickerElement, registerWidget, NcCustomPickerRenderResult } from '@nextcloud/vue/dist/Functions/registerReference.js'
registerWidget('my\_rich\_object\_type', async (el, { richObjectType, richObject, accessible, interactive }) \=> {
const { default: Vue } \= await import('vue')
const { default: MyWidget } \= await import('./views/MyWidget.vue')
const Widget \= Vue.extend(MyWidget)
const vueElement \= new Widget({
propsData: {
richObjectType,
richObject,
accessible,
interactive,
},
}).$mount(el)
return new NcCustomPickerRenderResult(vueElement.$el, vueElement)
}, (el, renderResult) \=> {
renderResult.object.$destroy()
}, true)
### Provide generic data for clients[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#provide-generic-data-for-clients "Link to this heading")
In the web interface, the links that your app resolves are rendered with the OpenGraph widget or the custom reference widget you implemented. So you have complete freedom on which data format you put in your rich objects because you also control the web rendering implementation.
But as the web UI components cannot be used by desktop or mobile clients, they have to specifically support some rich objects that are properly formatted.
Here are some formatting suggestions for a few use cases. Use them if you want your resolved links to be rendered in clients. The idea is to add a generic attribute in your rich objects, regardless of the rich object type.
#### Version control issue[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#version-control-issue "Link to this heading")
Set the rich object’s `vcs_issue` attribute to an object which contains those attributes:
* `id`: The issue ID (number)
* `url`: The issue page URL
* `title`: The issue title
* `comment_count`: The number of comments in the issue
* `state`: The issue state (‘open’ or ‘closed’)
* `labels`: An array of labels. A label is an object with those attributes:
* `color`: Hexadecimal color code
* `name`: The label name
* `created_at`: The creation timestamp
* `author`: The user ID or name of the issue creator
Example implementation: [GitHub integration issue link preview](https://github.com/nextcloud/integration_github/blob/e6792ea0aadef4f5b8faaaaa163a0cf473d86157/lib/Reference/GithubIssuePrReferenceProvider.php#L135)
#### Version control pull request[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#version-control-pull-request "Link to this heading")
Set the rich object’s `vcs_pull_request` attribute to an object which contains the same attributes as in `vcs_issue` plus these ones:
* `merged`: Is it merged? (boolean)
* `draft`: Is it a draft? (boolean)
Example implementation: [GitHub integration pull request link preview](https://github.com/nextcloud/integration_github/blob/e6792ea0aadef4f5b8faaaaa163a0cf473d86157/lib/Reference/GithubIssuePrReferenceProvider.php#L162)
#### Version control issue or pull request comment[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#version-control-issue-or-pull-request-comment "Link to this heading")
Set the rich object’s `vcs_comment` attribute to an object which contains those attributes:
* `url`: A direct link/permalink to the comment
* `body`: The comment content in plain text or markdown
* `author`: The user ID or name of the comment author
* `created_at`: The creation timestamp
* `updated_at`: The last edition timestamp
`vcs_comment` can be set in addition to `vcs_issue` or `vcs_pull_request`.
#### Images[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#images "Link to this heading")
Set the rich object’s `image_TYPE` attribute to `true`. The clients will then know they can render this as an image using the reference title, description and image URL that you have set.
Type can be `gif`, `jpeg`, `png` etc…
Example implementation: [Giphy integration](https://github.com/nextcloud/integration_giphy/blob/6c07af9c99014599bd3582a26e4fd99678b275ef/lib/Reference/GiphyReferenceProvider.php#L114-L124)
Extend the Smart Picker[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#extend-the-smart-picker "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you want your reference provider to appear in the Smart Picker to search/get links, it needs to be discoverable (extend the `OCP\Collaboration\Reference\ADiscoverableReferenceProvider` abstract class) and either
* support one or multiple Unified Search providers
* or register a custom picker component
This is an exclusive choice. You can’t support search providers AND register a custom picker component. If you still want to mix both approaches, you can register a custom picker component which includes a custom search feature.
Extending `ADiscoverableReferenceProvider` implies defining those methods:
* `getId`: returns an ID which will be used by the Smart Picker to identify this provider
* `getTitle`: returns a (ideally translated) provider title visible in the Smart Picker provider list
* `getOrder`: returns an integer to help sorting the providers. The sort order is later superseded by last usage timestamp
* `getIconUrl`: returns the URL of the provider icon, same as the title, the icon will be visible in the provider list
### Declare supported Unified Search providers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#declare-supported-unified-search-providers "Link to this heading")
If you want your reference provider to let users pick links from unified search results, your reference provider must implement `OCP\Collaboration\Reference\ISearchableReferenceProvider` and define the `getSupportedSearchProviderIds` method which return a list of supported search provider IDs.
Once this provider is selected in the Smart Picker, users will see a generic search interface giving results from all the search providers you declared as supported. Once a result is selected, the Smart Picker will return the associated resource URL.
### Register a custom picker component[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/reference.html#register-a-custom-picker-component "Link to this heading")
On the backend side, in your `lib/AppInfo/Application.php`, you should listen to the `OCP\Collaboration\Reference\RenderReferenceEvent`. In the corresponding listener, you should load the scripts that will register custom picker components.
In other words, when the `RenderReferenceEvent` event is dispatched, the Smart Picker will potentially by used in the frontend so you need to load the related scripts from your app.
You can define your own picker user interface for your provider by registering a custom picker component. This can be done with the `registerCustomPickerElement` function from `@nextcloud/vue/dist/Components/NcRichText.js`. This function takes 3 parameters:
* The reference provider ID for which you register the custom picker component
* The callback function to create and mount your component
* The callback function to delete/destroy your component
The creation callback must return a `NcCustomPickerRenderResult` object to which you have to give the DOM element you just created and optionally an object (the Vue instance for example). This render result will be then be passed to the destroy callback to let you properly clean and delete your custom component.
To register a Vue component as a custom picker component:
import { registerCustomPickerElement, NcCustomPickerRenderResult } from '@nextcloud/vue/dist/Components/NcRichText.js'
import Vue from 'vue'
import MyCustomPickerElement from './MyCustomPickerElement.vue'
registerCustomPickerElement('REFERENCE\_PROVIDER\_ID', (el, { providerId, accessible }) \=> {
const Element \= Vue.extend(MyCustomPickerElement)
const vueElement \= new Element({
propsData: {
providerId,
accessible,
},
}).$mount(el)
return new NcCustomPickerRenderResult(vueElement.$el, vueElement)
}, (el, renderResult) \=> {
// call the $destroy method on your custom element's Vue instance
renderResult.object.$destroy()
})
To register anything else:
import {
registerCustomPickerElement,
NcCustomPickerRenderResult,
} from '@nextcloud/vue/dist/Components/NcRichText.js'
registerCustomPickerElement('REFERENCE\_PROVIDER\_ID', (el, { providerId, accessible }) \=> {
const paragraph \= document.createElement('p')
paragraph.textContent \= 'click this button to return a link'
el.append(paragraph)
const button \= document.createElement('button')
button.textContent \= 'I am a button'
button.addEventListener('click', () \=> {
const event \= new CustomEvent(
'submit',
{
bubbles: true,
detail: 'https://nextcloud.com'
}
)
el.dispatchEvent(event)
})
el.append(button)
return new NcCustomPickerRenderResult(el)
}, (el, renderResult) \=> {
renderResult.element.remove()
})
In your custom component, just emit the `submit` event with the result as the event’s data to pass it back to the Smart Picker. You can also emit the `cancel` event to abort and go back.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Text Processing — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Text Processing
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/text_processing.rst)
* * *
Text Processing[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#text-processing "Link to this heading")
=========================================================================================================================================================
Added in version 27.1.0.
Deprecated since version 30: Use the TaskProcessing API instead
Nextcloud offers a **Text Processing** API. The overall idea is that there is a central OCP API that apps can use to prompt tasks to Large Language Models and similar text processing tools. To be technology agnostic any app can provide this functionality by registering Text Processing providers.
Consuming the Text Processing API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#consuming-the-text-processing-api "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To consume the Language Model API, you will need to [inject](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
`\OCP\TextProcessing\IManager`. This manager offers the following methods:
> * `hasProviders()` This method returns a boolean which indicates if any providers have been registered. If this is false you cannot use the TextProcessing feature.
>
> * `getAvailableTaskTypes()` This method returns a list of class strings representing the tasks that are currently supported.
>
> * `runTask(Task $task)` This method provides the actual prompt functionality. The task is defined using Task class. This method runs the task synchronously, so depending on the implementation it is uncertain how long it will take (between 3s - 10min).
>
> * `scheduleTask(Task $task)` This method provides the actual prompt functionality. The task is defined using the Task class. This method runs the task asynchronously in a background job.
>
> * `getTask(int $id)` This method fetches a task specified by its id.
>
Added in version 28.0.0:
* `runOrScheduleTask(Task $task)` This method also runs a task, but fist checks the expected runtime of the provider to be used. If the runtime fits inside the available processing time for the current request the task is run synchronously, otherwise it is scheduled as a background job. The task is defined using the Task class.
If you would like to use the text processing functionality in a client, there are also OCS endpoints available for this: [OCS Text Processing API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-textprocessing-api.html#ocs-textprocessing-api)
### Tasks types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#tasks-types "Link to this heading")
The following task types are available:
> * `\OCP\TextProcessing\FreePromptTaskType`: This task allows passing an arbitrary prompt to the language model.
>
> * `\OCP\TextProcessing\HeadlineTaskType`: This task will generate a headline for the passed input text.
>
> * `\OCP\TextProcessing\TopicsTaskType`: This task will generate a comma-separated list of topics for the passed input text.
>
> * `\OCP\TextProcessing\SummaryTaskType`: This task will summarize the passed input text.
>
### Tasks[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#tasks "Link to this heading")
To create a task we use the `\OCP\TextProcessing\Task` class. Its constructor takes the following arguments: `new \OCP\TextProcessing\Task(string $type, string $input, string $appId, ?string $userId, string $identifier = '')`. For example:
if (in\_array(SummaryTaskType::class, $textprocessingManager\->getAvailableTaskTypes()) {
$summaryTask \= new Task(SummaryTaskType::class, $emailText, "my\_app", $userId, (string) $emailId);
} else {
// cannot use summarization
}
The task class objects have the following methods available:
> * `getType()` This returns the task type.
>
> * `getStatus()` This method returns one of the below statuses.
>
> * `getId()` This method will return `null` before the task has been passed to `runTask` or `scheduleTask`
>
> * `getInput()` This returns the input string.
>
> * `getOutput()` This method will return `null` unless the task is successful
>
> * `getAppId()` This returns the originating application ID of the task.
>
> * `getIdentifier()` This returns the original scheduler-defined identifier for the task
>
> * `getUserId()` This returns the originating user ID of the task.
>
You could now run the task directly as follows. However, this will block the current PHP process until the task is done, which can sometimes take dozens of minutes, depending on which provider is used.
try {
$textprocessingManager\->runTask($summaryTask);
} catch (\\OCP\\PreConditionNotMetException|\\OCP\\TextProcessing\\Exception\\TaskFailureException $e) {
// task failed
// return error
}
// task was successful
The wiser choice, when you are in the context of a HTTP controller, is to schedule the task for execution in a background job, as follows:
try {
$textprocessingManager\->scheduleTask($summaryTask);
} catch (\\OCP\\PreConditionNotMetException|\\OCP\\DB\\Exception $e) {
// scheduling task failed
}
// task was scheduled successfully
#### Conditional scheduling of tasks[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#conditional-scheduling-of-tasks "Link to this heading")
Added in version 28.0.0.
Of course, you might want to schedule the task in a background job **only** if it takes longer than the request timeout. This is what `runOrScheduleTask` does.
try {
$textprocessingManager\->runOrScheduleTask($summaryTask);
} catch (\\OCP\\PreConditionNotMetException|\\OCP\\DB\\Exception $e) {
// scheduling task failed
// return error
} catch (\\OCP\\TextProcessing\\Exception\\TaskFailureException $e) {
// task was run but failed
// status will be STATUS\_FAILED
// return error
}
switch ($summaryTask\->getStatus()) {
case \\OCP\\TextProcessing\\Task::STATUS\_SUCCESSFUL:
// task was run directly and was successful
case \\OCP\\TextProcessing\\Task::STATUS\_RUNNING:
case \\OCP\\TextProcessing\\Task::STATUS\_SCHEDULED:
// task was deferred to background job
default:
// something went wrong
}
### Task statuses[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#task-statuses "Link to this heading")
All tasks always have one of the below statuses:
Task::STATUS\_FAILED \= 4;
Task::STATUS\_SUCCESSFUL \= 3;
Task::STATUS\_RUNNING \= 2;
Task::STATUS\_SCHEDULED \= 1;
Task::STATUS\_UNKNOWN \= 0;
### Listening to the text processing events[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#listening-to-the-text-processing-events "Link to this heading")
Since `scheduleTask` does not block, you will need to listen to the following events in your app to obtain the output or be notified of any failure.
> * `OCP\TextProcessing\Events\TaskSuccessfulEvent` This event class offers the `getTask()` method which returns the up-to-date task object, with the output from the model.
>
> * `OCP\TextProcessing\Events\TaskFailedEvent` In addition to the `getTask()` method, this event class provides the `getErrorMessage()` method which returns the error message as a string (only in English and for debugging purposes, so don’t show this to the user)
>
For example, in your `lib/AppInfo/Application.php` file:
$context\->registerEventListener(OCP\\TextProcessing\\Events\\TaskSuccessfulEvent::class, MyPromptResultListener::class);
$context\->registerEventListener(OCP\\TextProcessing\\Events\\TaskFailedEvent::class, MyPromptResultListener::class);
The corresponding `MyPromptResultListener` class can look like:
getTask()\->getAppId() !== Application::APP\_ID) {
return;
}
if ($event instanceof TaskSuccessfulEvent) {
$output \= $event\->getTask()\->getOutput()
// store $output somewhere
}
if ($event instanceof TaskFailedEvent) {
$error \= $event\->getErrorMessage()
$userId \= $event\->getTask()\->getUserId()
// Notify relevant user about failure
}
}
}
Implementing a TextProcessing provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#implementing-a-textprocessing-provider "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A **Text processing provider** is a class that implements the interface `OCP\TextProcessing\IProvider`.
l\->t('My awesome text processing provider');
}
public function getTaskType(): string {
return SummaryTaskType::class;
}
public function process(string $input): string {
// Return the output here
}
}
The method `getName` returns a string to identify the registered provider in the user interface.
The method `process` implements the text processing step, e.g. it passes the prompt to a language model. In case execution fails for some reason, you should throw a `RuntimeException` with an explanatory error message.
The class would typically be saved into a file in `lib/TextProcessing` of your app but you are free to put it elsewhere as long as it’s loadable by Nextcloud’s [dependency injection container](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
.
### Processing tasks in the context of a user[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#processing-tasks-in-the-context-of-a-user "Link to this heading")
Added in version 28.0.0.
Sometimes the processing of a text processing task may depend upon which user requested the task. You can now obtain this information in your provider by additionally implementing the `OCP\TextProcessing\IProviderWithUserId` interface:
l\->t('My awesome text processing provider');
}
public function getTaskType(): string {
return SummaryTaskType::class;
}
public function setUserId(?string $userId): void { $this\->userId \= $userId; }
public function process(string $input): string {
// Return the output here, making use of $this->userId
}
}
### Streamlining processing for fast providers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#streamlining-processing-for-fast-providers "Link to this heading")
Added in version 28.0.0.
Downstream consumers of the TextProcessing API can optimize execution of tasks if they know how long a task will run with your provider. To allow this kind of optimization you can provide an estimate of how much time your provider typically takes. To do this you simply implement the additional `OCP\TextProcessing\IProviderWithExpectedRuntime` interface
l\->t('My awesome text processing provider');
}
public function getTaskType(): string {
return SummaryTaskType::class;
}
public function getExpectedRuntime(): int { return 10; // expected runtime of a task is 10s }
public function process(string $input): string {
// Return the output here
}
}
### Providing more task types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#providing-more-task-types "Link to this heading")
If you would like to implement providers that handle additional task types, you can create your own TaskType classes implementing the `OCP\TextProcessing\ITaskType` interface:
l\->t('Oscar Wilde Generator');
}
public function getDescription(): string {
return $this\->l\->t('Turn text into Oscar Wilde prose');
}
}
Provider registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#provider-registration "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------
The provider class is registered via the [bootstrap mechanism](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
of the `Application` class.
registerTextProcessingProvider(Provider::class); }
public function boot(IBootContext $context): void {}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Snowflake IDs — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Snowflake IDs
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/snowflake_ids.rst)
* * *
Snowflake IDs[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html#snowflake-ids "Link to this heading")
===================================================================================================================================================
Added in version 33.
Nextcloud integrates a customized version of Snowflake IDs ([https://en.wikipedia.org/wiki/Snowflake\_ID](https://en.wikipedia.org/wiki/Snowflake_ID)
).
It allows to generates unique IDs in advance and also contains information about creation:
* creation time at millisecond precision
* identifier of server which created the ID. It’s usually a hash of server hostname or random if not hostname found.
* whether the ID was created from CLI or not
Store a Snowflake ID in database[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html#store-a-snowflake-id-in-database "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Snowflake IDs are designed to be used as primary key in database. They should be stored as `UNSIGNED BIGINT` (64 bits integer, always positive)
In Nextcloud migrations it looks like:
public function changeSchema(IOutput $output, Closure $schemaClosure, array $options): ?ISchemaWrapper {
/\*\* @var ISchemaWrapper $schema \*/
$schema \= $schemaClosure();
if (!$schema\->hasTable('my\_table')) {
$table \= $schema\->createTable('my\_table');
$table\->addColumn(
'id',
Types::BIGINT,
\['notnull' \=> true, 'unsigned' \=> true\]
);
$table\->setPrimaryKey(\['id'\]);
// TODO Add other fields
}
Generate a Snowflake ID[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html#generate-a-snowflake-id "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
To generate a new ID, call `nextId` function on the generator:
generator\->nextId();
// TODO Create other properties and insert into database
}
}
Decode a Snowflake ID[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/snowflake_ids.html#decode-a-snowflake-id "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
IDs can be decoded with `occ snowflake:decode ` command.
It’s also possible to decode IDs in your code, for example to get creation time of your object:
decoder\->decode($this\->id)\['createdAt'\];
}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Android — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* Android
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/android_library/index.rst)
* * *
Android[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/android_library/index.html#android "Link to this heading")
============================================================================================================================================
Nextcloud provides an official Nextcloud Android client, which gives its users access to their files on their Nextcloud. It also includes functionality like automatically uploading pictures and videos to Nextcloud.
For third party application developers, Nextcloud offers the Nextcloud Android library under the MIT license.
Android Nextcloud client development[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/android_library/index.html#android-nextcloud-client-development "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
If you are interested in working on the Nextcloud Android client, you can find the source code [in GitHub](https://github.com/nextcloud/android/)
. The setup and process of contribution is [documented here](https://github.com/nextcloud/android/blob/master/SETUP.md)
.
You might want to start with doing one or two [good first issues](https://github.com/nextcloud/android/labels/good%20first%20issue)
to get into the code and note our [Prologue](https://docs.nextcloud.com/server/latest/developer_manual/prologue/index.html)
.
For authentication, you can use our usual login flow, and in addition (or instead if you are OK for users to depend on our Files app) use the great [Android SingleSignOn library](https://github.com/nextcloud/Android-SingleSignOn/#how-to-use-this-library)
Nextcloud Android library[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/android_library/index.html#nextcloud-android-library "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
This document will describe how to the use Nextcloud Android Library. The Nextcloud Android Library allows a developer to communicate with any Nextcloud server; among the features included are file synchronization, upload and download of files, delete or rename files and folders, etc.
This library may be added to a project and seamlessly integrates any application with Nextcloud.
The tool needed is any IDE for Android; the preferred IDE at the moment is Android Studio.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Activity — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* Activity
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/activity-api.rst)
* * *
Activity[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/activity-api.html#activity "Link to this heading")
=====================================================================================================================================
Find the documentation in the [Activity app repo](https://github.com/nextcloud/activity/blob/master/docs/endpoint-v2.md)
.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# General — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* General
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/general.rst)
* * *
General[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/general.html#general "Link to this heading")
==============================================================================================================================
Nextcloud’s APIs are mainly available through [REST APIs](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/rest_apis.html#rest-apis)
, [OCS](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/index.html#ocsapiindex)
and [Webdav](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/index.html#webdavapiindex)
.
Generic Errors[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/general.html#generic-errors "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------
Additional to specific errors of an API, there are a few generic errors Nextcloud might throw on web APIs.
### Maintenance Mode[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/general.html#maintenance-mode "Link to this heading")
If Nextcloud is down for maintenance, it sends a HTTP response with status code 503 and the header `x-nextcloud-maintenance-mode: 1`.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Login Flow — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* Login Flow
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/LoginFlow/index.rst)
* * *
Login Flow[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#login-flow "Link to this heading")
============================================================================================================================================
This document provides a quick overview of the new login flow that should be used by clients to obtain login credentials. This will assure that each client gets its own set of credentials. This has several advantages:
1. A client never stores the password of the user
2. The user can revoke access on a per client basis from the web
Opening the webview[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#opening-the-webview "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------
The client should open a webview to `/index.php/login/flow`. Be sure to set the `OCS-APIREQUEST` header to `true`.
The client will register a URL handler to catch urls of the `nc` protocol. This is required to obtain the credentials in the final stage.
This should be a one time webview. Which means:
* There should be no cookies set when creating the webview
* Passwords should not be stored
* No state should be preserved after the webview has terminated
To have a good user experience please consider the following things:
* set a proper `ACCEPT_LANGUAGE` header
* set a proper `USER_AGENT` header
Login in the user[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#login-in-the-user "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
The user will now see a webpage telling them they will grant access to `USER_AGENT`. When they follow the steps they will be asked to login. If they have two factor authentication enabled they will require this to login. But since this is all in the webview itself the client does not need to care about this.
Obtaining the login credentials[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#obtaining-the-login-credentials "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
On the final login the server will do a redirect to a url of the following format:
nc://login/server:&user:&password:
* `server`: The address of the server to connect to. The server may specify a protocol (http or https). If no protocol is specified the client will assume https.
* `loginname`: The username that the client must use to login. **Note:** Keep in mind that this is the loginname and could be different from the username. For example the email address could be used to login but not for generating the webdav URL. You could fetch the actual username from the OCS API endpoint `/ocs/v1.php/cloud/user`.
* `password`: The password that the client must use to login and store securely
Note
`loginname` and `password` are encoded by PHP’s [urlencode](https://www.php.net/manual/en/function.urlencode.php)
, which differs from [RFC 3986](http://www.faqs.org/rfcs/rfc3986.html)
. You may need to replace plus signs `'+'` with spaces `' '` before decoding.
This information will be used by the client to create a new account. After this the webview is destroyed including all the state the webview holds.
Converting to app passwords[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#converting-to-app-passwords "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Old configurations of clients might still be using username and passwords. The login flow ensures that each device has an unique app password. In order to facilitate transparent migration to app passwords there is an endpoint that can be called by client.
If the client is authenticated with an app password a 403 will be returned. If the client is authenticating with a real password an app password will be generated and returned.
The user agent header will be used to name the app password.
curl \-u username:password \-H 'OCS-APIRequest: true' https://cloud.example.com/ocs/v2.php/core/getapppassword
The response would look (in XML) something like:
ok200OKM1DqHwuZWwjEC3ku7gJsspR7bZXopwf01kj0XGppYVzEkGtbZBRaXlOUxFZdbgJ6Zk9OwG9x
Deleting an app password[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#deleting-an-app-password "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------
When an account on a client is removed for housekeeping it is desired to destroy the apptoken in use. This can be done by a simple call:
curl \-u username:app-password \-X DELETE \-H 'OCS-APIREQUEST: true' http://localhost/ocs/v2.php/core/apppassword
The response should be a plain OCS response with a status 200
ok200OK
If a non 200 status code is returned the client should still proceed with removing the account.
Login flow v2[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#login-flow-v2 "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
While the login flow works very nice in a lot of cases there are especially on desktop application certain hurdles. Special proxy configuration, client side certificates and the likes can cause trouble. To solve this we have come up with a second login flow that uses the users default webbrowser to authenticate. Thus ensuring that if they can login via the web they can also login in the client.
To initiate a login do an anonymous POST request
curl \-X POST https://cloud.example.com/index.php/login/v2
This will return a json object like
{
"poll":{
"token":"mQUYQdffOSAMJYtm8pVpkOsVqXt5hglnuSpO5EMbgJMNEPFGaiDe8OUjvrJ2WcYcBSLgqynu9jaPFvZHMl83ybMvp6aDIDARjTFIBpRWod6p32fL9LIpIStvc6k8Wrs1",
"endpoint":"https:\\/\\/cloud.example.com\\/login\\/v2\\/poll"
},
"login":"https:\\/\\/cloud.example.com\\/login\\/v2\\/flow\\/guyjGtcKPTKCi4epIRIupIexgJ8wNInMFSfHabACRPZUkmEaWZSM54bFkFuzWksbps7jmTFQjeskLpyJXyhpHlgK8sZBn9HXLXjohIx5iXgJKdOkkZTYCzUWHlsg3YFg"
}
The url in login should be opened in the default browser, this is where the user will follow the login procedure. The program should directly start polling the poll endpoint:
curl \-X POST https://cloud.example.com/login/v2/poll \-d "token=mQUYQdffOSAMJYtm8pVpkOsVqXt5hglnuSpO5EMbgJMNEPFGaiDe8OUjvrJ2WcYcBSLgqynu9jaPFvZHMl83ybMvp6aDIDARjTFIBpRWod6p32fL9LIpIStvc6k8Wrs1"
The token will be valid for 20 minutes. This will return a 404 until authentication is done. Once a 200 is returned it is another json object.
{
"server":"https:\\/\\/cloud.example.com",
"loginName":"username",
"appPassword":"yKTVA4zgxjfivy52WqD8kW3M2pKGQr6srmUXMipRdunxjPFripJn0GMfmtNOqOolYSuJ6sCN"
}
Use the server and the provided credentials to connect. Note that the 200 will only be returned once.
Troubleshooting[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#troubleshooting "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
### Login name vs. email login[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/LoginFlow/index.html#login-name-vs-email-login "Link to this heading")
Nextcloud allows authentication with user’s _login name_, which can be their UID, an email address and similar. The identifier used for the session in which the user generates the app password will be stored into the database record of the generated app password. Therefore the identifier used in the web session that authorizes a client must match the identifier used in the connecting client.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Files — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* Files
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/files.rst)
* * *
Files[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/files.html#files "Link to this heading")
========================================================================================================================
Added in version 27.
Since Nextcloud 27, the files app has been rewritten to use new standards and frameworks. This means that the old documentation is no longer valid. We will update and document the new files app APIs and methods here.
Note
Some external libraries offers in-depth technical documentation. Please have a look at the following:
* [https://github.com/nextcloud-libraries/nextcloud-event-bus](https://github.com/nextcloud-libraries/nextcloud-event-bus)
([documentation](https://nextcloud-libraries.github.io/nextcloud-event-bus)
)
* [https://github.com/nextcloud-libraries/nextcloud-files](https://github.com/nextcloud-libraries/nextcloud-files)
([documentation](https://nextcloud-libraries.github.io/nextcloud-files)
)
* [https://github.com/nextcloud-libraries/nextcloud-upload](https://github.com/nextcloud-libraries/nextcloud-upload)
([documentation](https://nextcloud-libraries.github.io/nextcloud-upload)
)
Events[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/files.html#events "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------
To listen to files or folder changes or to trigger changes, you need to use the `event-bus` and use the following events:
> * `files:node:created`: the node has been created
>
> * `files:node:deleted`: the node has been deleted
>
> * `files:node:moved`: the node has been moved (and its data is already updated)
>
> * `files:node:updated`: the node data has been updated
>
All these events use a Node as argument. You can use a webdav client (for example, by using the davGetClient function from [@nextcloud/files](https://nextcloud-libraries.github.io/nextcloud-files/)
) to retrieve a node from a file’s name.
### Examples[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/files.html#examples "Link to this heading")
import type { Node } from '@nextcloud/files'
import { subscribe } from '@nextcloud/event-bus'
subscribe('files:node:created', (node: Node) \=> {
console.log('Node created', node)
})
Router[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/files.html#router "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------
To change views and parameters of the current Files app, we expose the router. This directly maps to the Vue router. You can check their own [documentation](https://router.vuejs.org/guide/essentials/navigation.html#navigate-to-a-different-location)
to better understand the methods.
/\*\*
\* Trigger a route change on the files app
\*
\* @param path the url path, eg: '/trashbin?dir=/Deleted'
\* @param replace replace the current history
\* @see https://router.vuejs.org/guide/essentials/navigation.html#navigate-to-a-different-location
\*/
goTo(path: string, replace: boolean \= false): Promise
/\*\*
\* Trigger a route change on the files App
\*
\* @param name the route name
\* @param params the route parameters
\* @param query the url query parameters
\* @param replace replace the current history
\* @see https://router.vuejs.org/guide/essentials/navigation.html#navigate-to-a-different-location
\*/
goToRoute(
name?: string,
params?: Dictionary,
query?: Dictionary,
replace?: boolean,
): Promise
### Examples[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/files.html#id1 "Link to this heading")
OCP.Files.Router.goTo('/trashbin?dir=/Unsplash.d1680193199')
OCP.Files.Router.goToRoute('fileslist', { view: 'files' }, { dir: '/Folders/Group folder' })
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Remote wipe — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* Remote wipe
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/RemoteWipe/index.rst)
* * *
Remote wipe[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/RemoteWipe/index.html#remote-wipe "Link to this heading")
===============================================================================================================================================
This document provides a quick overview of the remote wipe API that should be used by clients to implement the remote wipe functionality. This will allow users to wipe a lost device for example.
Note that wiping only works when clients use the login flow so that a dedicated token is set for this client.
Obtaining wipe status[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/RemoteWipe/index.html#obtaining-wipe-status "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Once a client receives a 401 or 403 status response it will do a fetch to `/index.php/core/wipe/check` and set the token parameter to the apptoken.
curl https://cloud.example.com/index.php/core/wipe/check \-X POST \-d 'token='
In case the client gets back a 200 status code and a JSON array with wipe set to true like:
{
"wipe":true
}
then the client should proceed to wipe the device.
Wiping the actual device[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/RemoteWipe/index.html#wiping-the-actual-device "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The client must remove all user data linked to the account. This includes:
* caches
* offline files
* the actual account itself
Signalling completion[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/RemoteWipe/index.html#signalling-completion "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Once the client has wiped all the required data a POST to `/index.php/core/wipe/success` has to be made with the token. This signals the server the wipe is completed and triggers the final cleanup on the server side.
curl https://cloud.example.com/index.php/core/wipe/success \-X POST \-d 'token='
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Client Integration — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* Client Integration
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/ClientIntegration/index.rst)
* * *
Client Integration[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#client-integration "Link to this heading")
====================================================================================================================================================================
With Nextcloud Hub 26 Winter we are introducing a new client integration API. It allows server side apps to expose integrations on Desktop and Mobile. For now we support adding app-defined actions to a “context menu” of files and folders.
It allows providing easy integration of specific actions on clients without the need to write and maintain code on those platforms.
Supported clients[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#supported-clients "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
Android: 3.36.0 and above
Desktop: 33.0.0 and above
iOS: 7.3.0 and above
Supported server apps[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#supported-server-apps "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------
richdocuments: Convert .docx to .md
assistant: Transcribe audio file
files\_zip: Zip a file or folder
contacts: Create new contact from vfc
Exposing actions via capability[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#exposing-actions-via-capability "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Each app can add new actions via capabilities, following the syntax “app-id”, “hook-name” and list of all endpoints.
'client\_integration' \=> \[\
Application::APP\_ID \=> \[\
'version' \=> 0.1,\
'context-menu' \=> \[\
// ... endpoints ...\
\]\
\]\
\]
Hooks[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#hooks "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------
Currently only “context-menu” is supported.
Endpoint[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#endpoint "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------
The endpoint tells the client how the menu entry should look like and how the client can send a request to the server.
Requirements:
* Every text need to be translated by the app itself.
* Current predefined params are `fileId` and `filePath`,
* `{fileId}` and `{filePath}` will be replaced by clients with actual values,
* `url` placeholders are always replaced,
* `mimetype_filters` is a comma-separated list of filters (matches anything that starts with the filter). If there is no filter, the action is shown for every file/folder.
* All `urls` must be relative.
* `params` is used for body params (currently only POST).
* `icon` field should always provide an SVG.
* `method` supports POST/GET.
\[\
'name' \=> 'translated title',\
'url' \=> '/ocs/v2.php/apps/abc',\
'method' \=> 'POST/GET',\
'mimetype\_filters' \=> 'text/, application/pdf', // will match text/\* and PDFs\
'params' \=> \['file\_id' \=> '{fileId}','file\_path' \=> '{filePath}'\], // only for POST; the key can vary depending on the app\
'icon' \=> '/apps/abc/img/app.svg'\
\],
Responses[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#responses "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
When clicking on a menu entry the client sends a predefined request to the server. The app in question can then handle the request and can send two different response types:
### Declarative UI response[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#declarative-ui-response "Link to this heading")
The declarative UI response allows the app to send back a new UI to be rendered by the client: - version: Indicates which version it is. Clients will be backwards compatible. If server sends a newer version than the client can understand the response will be ignored. - tooltip: Translated text, which will be shown as tooltip / snackbar.
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"version": 0.1,
"root": {
"orientation": "vertical",
"rows": \[\
{\
"children": \[\
{\
"element": "URL",\
"text": "Link created",\
"url": "/some/link/to/a/page"\
}\
\]\
}\
\]
}
}
}
}
At the moment only rows with text and url elements are supported, but in the future we will add more elements and options.
### Tooltip Response[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#tooltip-response "Link to this heading")
The tooltip response is a regular DataResponse type, with payload: - version: Indicates which version it is. Clients will be backwards compatible. If server sends a newer version than the client can understand the response will be ignored. - tooltip: Translated text, which will be shown as tooltip / snackbar.
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"version": "0.1",
"tooltip": "Task submitted successfully"
}
}
}
Example[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#example "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------
Here is an example of using the Assistant app.
**Capabilities:**
ocs/v1.php/cloud/capabilities returns the following capability:
"client\_integration": {
"assistant": {
"version": 0.1,
"context-menu": \[\
{\
"name": "Summarize using AI",\
"url": "/ocs/v2.php/apps/assistant/api/v1/file-action/{fileId}/core:text2text:summary",\
"method": "POST",\
"mimetype\_filters": "text/, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.oasis.opendocument.text, application/pdf",\
"icon": "/apps/assistant/img/client\_integration/summarize.svg"\
},\
{\
"name": "Transcribe audio using AI",\
"url": "/ocs/v2.php/apps/assistant/api/v1/file-action/{fileId}/core:audio2text",\
"method": "POST",\
"mimetype\_filters": "audio/",\
"icon": "/apps/assistant/img/client\_integration/speech\_to\_text.svg"\
},\
{\
"name": "Text-To-Speech using AI",\
"url": "/ocs/v2.php/apps/assistant/api/v1/file-action/{fileId}/core:text2speech",\
"method": "POST",\
"mimetype\_filters": "text/, application/msword, application/vnd.openxmlformats-officedocument.wordprocessingml.document, application/vnd.oasis.opendocument.text, application/pdf",\
"icon": "/apps/assistant/img/client\_integration/text\_to\_speech.svg"\
}\
\]
},
},
The Assistant integration has a few endpoints for the client to show and execute. “Summarize using AI” and “Text-To-Speech using AI” appears at the bottom of each menu on the client side:
[](https://docs.nextcloud.com/server/latest/developer_manual/_images/client-integration-ios.png)
[](https://docs.nextcloud.com/server/latest/developer_manual/_images/client-integration-android.png)
Looking at the “Summarize using AI” action, it will only show for files with mimetypes starting with “text/” or the specified document and PDF mimetypes, as described in mimetype\_filters. When clicking on the action, the client will send a POST request to the specified URL, replacing {fileId} with the actual file id. The app can then handle the request and for example send a tooltip response back to the client. The client will show the tooltip to the user:
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": "OK"
},
"data": {
"version": 0.1,
"tooltip": "Summarization task submitted successfully"
}
}
}
Develop your first app with client integration[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#develop-your-first-app-with-client-integration "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1. Familiarize yourself on how to create an app via [Develop your first Hello World app](https://cloud.nextcloud.com/s/iyNGp8ryWxc7Efa?dir=%2F%2F2%20Develop%20your%20first%20Hello%20World%20app)
for more help on that topic:
2. Create `Capabilities.php` in `/lib` folder and add to array in `getCapabilities()`:
> 'client\_integration' \=> \[\
> 'pingpong' \=> \[\
> 'version' \=> 0.1,\
> 'context-menu' \=> \[\
> \[\
> 'name' \=> $this\->l10n\->t('Ping'),\
> 'url' \=> '/ocs/v2.php/apps/pingpong/ping/{fileId}',\
> 'method' \=> 'GET',\
> \],\
> \],\
> \],\
> \],
See [Endpoint](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#endpoint-section)
for endpoint details.
3. Register the app in `lib/AppInfo/Application.php`
> public function register(IRegistrationContext $context): void {
> $context\->registerCapability(Capabilities::class);
> }
4. Add consuming function in `/lib/Controller/ApiController.php`:
> #\[NoAdminRequired\]
> #\[ApiRoute(verb: 'GET', url: '/ping/{fileId}')\]
> public function ping(int $fileId \= 1): DataResponse {
> return new DataResponse(
> \['version' \=> 0.1,\
> 'tooltip' \=> $this\->l10n\->t("Pong file %s", $fileId)\]
> );
> }
5. Response is `DataResponse` with a version (currently 0.1) and a translated tooltip.
Issues/Bugs[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/ClientIntegration/index.html#issues-bugs "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
Please report issues, bugs or feature requests at [https://github.com/nextcloud/files-clients](https://github.com/nextcloud/files-clients)
with label “Client integration”.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Webdav — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* Webdav
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/WebDAV/index.rst)
* * *
Webdav[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/index.html#webdav "Link to this heading")
=================================================================================================================================
* [Basic APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html)
* [WebDAV basics](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#webdav-basics)
* [Testing requests](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#testing-requests)
* [Requesting properties](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#requesting-properties)
* [Listing folders (rfc4918)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#listing-folders-rfc4918)
* [Downloading files](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#downloading-files)
* [Downloading folders](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#downloading-folders)
* [Uploading files](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#uploading-files)
* [Creating folders (rfc4918)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#creating-folders-rfc4918)
* [Deleting files and folders (rfc4918)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#deleting-files-and-folders-rfc4918)
* [Moving files and folders (rfc4918)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#moving-files-and-folders-rfc4918)
* [Copying files and folders (rfc4918)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#copying-files-and-folders-rfc4918)
* [Settings favorites](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#settings-favorites)
* [Listing favorites](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#listing-favorites)
* [Special Headers](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#special-headers)
* [Response Headers](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/basic.html#response-headers)
* [Search](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/search.html)
* [Making search requests](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/search.html#making-search-requests)
* [Supported DAV properties](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/search.html#supported-dav-properties)
* [Search scope](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/search.html#search-scope)
* [Examples search bodies](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/search.html#examples-search-bodies)
* [Trashbin](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/trashbin.html)
* [Listing the trashbin content](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/trashbin.html#listing-the-trashbin-content)
* [Restoring from the trashbin](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/trashbin.html#restoring-from-the-trashbin)
* [Deleting from the trashbin](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/trashbin.html#deleting-from-the-trashbin)
* [Emptying the trashbin](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/trashbin.html#emptying-the-trashbin)
* [Versions](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/versions.html)
* [Listing the versions of a file](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/versions.html#listing-the-versions-of-a-file)
* [Restoring a version](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/versions.html#restoring-a-version)
* [Chunked file upload](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/chunking.html)
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/chunking.html#introduction)
* [Chunked upload v2](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/chunking.html#chunked-upload-v2)
* [File bulk upload](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/bulkupload.html)
* [Introduction](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/bulkupload.html#introduction)
* [Usage](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/bulkupload.html#usage)
* [Comments](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/comments.html)
* [Endpoint](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/WebDAV/comments.html#endpoint)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# WebDAV collection preload events — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* WebDAV collection preload events
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/webdav_collection_preload.rst)
* * *
WebDAV collection preload events[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#webdav-collection-preload-events "Link to this heading")
=====================================================================================================================================================================================================
Overview[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#overview "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------
During a WebDAV PROPFIND on a SabreDAV collection with `Depth > 0`, Nextcloud emits a preload event so DAV plugins can fetch data for the collection’s children in one go. The goal is to avoid N+1 database queries by preloading what your property handlers need before per-node property handling starts. In practice, this means your plugin can fill a cache up front, then read from it in the usual `propFind` handlers for a faster and more efficient response.
When the event is emitted[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#when-the-event-is-emitted "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
The event is emitted during PROPFIND requests, before the `propFind` event, for nodes implementing `Sabre\DAV\ICollection` with `Depth > 0`.
The event may be emitted multiple times for a given request path; plugins should check their caches to avoid duplicate work.
Subscribing to the event in a plugin[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#subscribing-to-the-event-in-a-plugin "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Register a listener in your implementation of Sabre’s `ServerPlugin::initialize()` method:
use Sabre\\DAV\\ICollection;
use Sabre\\DAV\\PropFind;
use Sabre\\DAV\\ServerPlugin;
class MyDavPlugin extends ServerPlugin {
public function initialize(\\Sabre\\DAV\\Server $server): void {
// Called before per-node property handlers
$server\->on('preloadCollection', $this\->preloadCollection(...));
// Your usual property handlers
$server\->on('propFind', $this\->handleGetProperties(...));
}
private function preloadCollection(PropFind $propFind, ICollection $collection): void {
// Only preload when your properties were actually requested
$requested \= \[\
'{http://appdomain.example/ns}your-prop',\
'{http://appdomain.example/ns}another-prop',\
\];
$anyRequested \= array\_reduce(
$requested,
fn($result, $property) \=> $result || $propFind\->getStatus($property) !== null,
false
);
if (!$anyRequested) {
return;
}
// Fetch data for the collection and its children in bulk
// and cache results for use in your propFind handler
$this\->cache \= $this\->bulkLoadDataForCollection($collection); // implement your own caching
}
private function handleGetProperties(PropFind $propFind, \\Sabre\\DAV\\INode $node): void {
// Read and return values from $this->cache to avoid per-node queries
// Handle per-node property loading here to support Depth = 0
// and cases where the 'preloadCollection' event is not emitted.
}
}
Built-in examples[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#built-in-examples "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
* Tags: `OCA\DAV\Connector\Sabre\TagsPlugin` preloads tags and favorite info for a folder and its children.
* Shares: `OCA\DAV\Connector\Sabre\SharesPlugin` preloads share types and sharees for items within a folder.
* Comments: `OCA\DAV\Connector\Sabre\CommentPropertiesPlugin` preloads unread comment counts for items within a folder.
Best practices[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/webdav_collection_preload.html#best-practices "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
* Check requested properties: Use `$propFind->getStatus('{ns}property')` to confirm that your properties were actually requested before querying.
* Cache results: The event can fire multiple times; cache by file ID or path to avoid redundant work during the same request.
* Scope your preload: Only fetch data for the current collection and (at most) its direct children; avoid fetching across the whole tree.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# The Nextcloud app store rules — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/index.html)
* The Nextcloud app store rules
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_publishing_maintenance/publishing.rst)
* * *
The Nextcloud app store rules[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#the-nextcloud-app-store-rules "Link to this heading")
============================================================================================================================================================================================
The Nextcloud app store is built into Nextcloud to allow you to get your apps to users as easily and safely as possible. The app store and the process of publishing apps aims to be:
* secure
* transparent
* welcoming
* fair
* easy to maintain
Losing a rating[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#losing-a-rating "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
Apps can lose their rating when:
* they are found to no longer satisfy the requirements
* when security/malicious intent issues are found
* when a developer requests so
App guidelines[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#app-guidelines "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------
These are the app guidelines an app has to comply with to have a chance to be approved.
### Legal and security[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#legal-and-security "Link to this heading")
* Apps must be licensed under AGPL-3.0-or-later or any compatible license.
* Apps must not use ‘Nextcloud’ in their name.
* Irregular and unannounced security audits of all apps can and will take place.
* If any indication of malicious intent or bad faith is found the developer(s) in question can count on a minimum 2 year ban from any Nextcloud infrastructure.
* Malicious intent includes deliberate spying on users by leaking user data to a third party system or adding a back door (like a hard-coded user account) to Nextcloud. An unintentional security bug that gets fixed in time won’t be considered bad faith.
* Apps do not violate any laws; it has to comply with copyright- and trademark law.
* App authors have to respond timely to security concerns and not make Nextcloud more vulnerable to attacks.
Note
Distributing malicious or illegal applications can have legal consequences including, but not limited to Nextcloud or affected users taking legal action.
### Be technically sound[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#be-technically-sound "Link to this heading")
* Apps can only use the public Nextcloud API.
* At time of the release of an app it can only be configured to be compatible with the latest Nextcloud release +1.
* Apps should not cause Nextcloud to break, consume excessive memory or slow Nextcloud down.
* Apps should not hamper functionality of Nextcloud unless that is explicitly the goal of the app.
### Respect the users[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#respect-the-users "Link to this heading")
* Apps have to follow design and [HTML/CSS layout guidelines](https://docs.nextcloud.com/server/latest/developer_manual/app/css.html)
.
* Apps correctly clean up after themselves on uninstall and correctly handle up- and downgrades.
* Apps clearly communicate their intended purpose and active features, including features introduced through updates.
* Apps respect the users’ choices and do not make unexpected changes, or limit users’ ability to revert them. For example, they do not remove other apps or disable settings.
* Apps must respect user privacy. IF user data is sent anywhere, this must be clearly explained and be kept to a minimum for the functioning of an app. Use proper security measures when needed.
* App authors must provide means to contact them, be it through a bug tracker, forum or mail.
Apps which break the guidelines will lose their ‘approved’ or ‘official’ state; and might be blocked from the app store altogether. This also has repercussions for the author, especially in case of security concerns, they might find themselves blocked from submitting applications.
Moving your repo to the Nextcloud organization[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#moving-your-repo-to-the-nextcloud-organization "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
We’re always delighted to hear app developers are interested in moving their app to the Nextcloud organization at [github.com/nextcloud](https://github.com/nextcloud)
! There are benefits for users and developers in being there. However, it comes with some requirements as well.
### Benefits[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#benefits "Link to this heading")
* You can use the tools and bots we have set up, including translations and such
* Everybody in the Nextcloud organization can contribute more easily
* Your visibility to app developers increases
* Users can expect apps in our project to be better maintained
### Requirements[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#requirements "Link to this heading")
To deliver on the promises above, we have two simple rules.
* You work and communicate according to the values of our [Code of Conduct](https://nextcloud.com/contribute/code-of-conduct/)
* When you are no longer active, our admins can decide to hand over maintainership to another contributor
We want to make sure that when you find other things in life which are more urgent or otherwise are unable to help your project anymore, it does not become ‘dead code’ as long as there are people who want to keep it alive. This is not fair to users, who would be forced to remove the app and install another.
Please note that the role of a maintainer is not to be the most active or prolific contributor to a project! Being friendly, welcoming and responsive are what it takes to be a successful maintainer. Not being the most brilliant developer ever, or spending nights and weekends coding!
The goal of these rules is simple: help your project be more successful. We also suggest you watch this talk by [Jan about building a great community.](https://www.youtube.com/watch?v=UtAoRIKVpW4)
### How to move[](https://docs.nextcloud.com/server/latest/developer_manual/app_publishing_maintenance/publishing.html#how-to-move "Link to this heading")
To move your repository to our GitHub organization, just ask any of our contributors, [especially those who are admin.](https://github.com/orgs/nextcloud/people?utf8=%E2%9C%93&query=+role%3Aowner)
They will be happy to help!
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Context Chat — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Context Chat
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/context_chat.rst)
* * *
Context Chat[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#context-chat "Link to this heading")
================================================================================================================================================
Added in version 32.0.0.
Nextcloud offers a **Context Chat** API which allows apps like files to submit data to the [Nextcloud Assistant Context Chat](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_context_chat.html)
, thereby enabling [Nextcloud Assistant](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html)
to answer questions, provide insights and search results based on the submitted data and natural language queries.
Implementing a content provider for Context Chat[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#implementing-a-content-provider-for-context-chat "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
### The IContentProvider interface[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#the-icontentprovider-interface "Link to this heading")
A content provider for Context Chat needs to implement the `\OCP\ContextChat\IContentProvider` interface:
/\*\*
\* This interface defines methods to implement a content provider
\* @since 32.0.0
\*/
interface IContentProvider {
/\*\*
\* The ID of the provider
\*
\* @return string
\* @since 32.0.0
\*/
public function getId(): string;
/\*\*
\* The ID of the app making the provider available
\*
\* @return string
\* @since 32.0.0
\*/
public function getAppId(): string;
/\*\*
\* The absolute URL to the content item
\*
\* @param string $id
\* @return string
\* @since 32.0.0
\*/
public function getItemUrl(string $id): string;
/\*\*
\* Starts the initial import of content items into context chat
\*
\* @return void
\* @since 32.0.0
\*/
public function triggerInitialImport(): void;
}
The `triggerInitialImport` method is called when Context Chat is first set up and allows your app to import all existing content into Context Chat in one bulk. Any other items that are created afterwards will need to be added on demand.
### Using the IContentManager service[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#using-the-icontentmanager-service "Link to this heading")
To add content and register your provider implementation you will need to use the `\OCP\ContextChat\IContentManager` service.
The `IContentManager` class has the following methods:
> * `isContextChatAvailable()`: Returns `true` if the Context Chat app is enabled, `false` otherwise.
>
> * `registerContentProvider(string $providerClass)`: Register a new content provider.
>
> * `submitContent(string $appId, array $items)`: Providers can use this to submit content for indexing in Context Chat.
>
> * `updateAccess(string $appId, string $providerId, string $itemId, string $op, array $userIds)`: Update the access rights for a content item. Use `\OCP\ContextChat\Type\UpdateAccessOp` constants for the `$op` value.
>
> * `updateAccessProvider(string $appId, string $providerId, string $op, array $userIds)`: Update the access rights for all content items from a provider. Use `\OCP\ContextChat\Type\UpdateAccessOp` constants for the `$op` value.
>
> * `updateAccessDeclarative(string $appId, string $providerId, string $itemId, array $userIds)`: Update the access rights for a content item. This method is declarative and will replace the current access rights with the provided ones.
>
> * `deleteProvider(string $appId, string $providerId)`: Remove all content items of a provider from the knowledge base of Context Chat.
>
> * `deleteContent(string $appId, string $providerId, array $itemIds)`: Remove specific content items from the knowledge base of Context Chat.
>
### Implementing the ContentProviderRegisterEvent event[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#implementing-the-contentproviderregisterevent-event "Link to this heading")
To register your content provider, your app needs to listen to the `OCP\ContextChat\Events\ContentProviderRegisterEvent` event and call the `registerContentProvider` method in the event for every provider you want to register.
Some partial implementations of `Application.php` and a `ContentProvider` for reference:
use OCA\\MyApp\\ContextChat\\ContentProvider;
use OCP\\ContextChat\\Events\\ContentProviderRegisterEvent;
// ...
$context\->registerEventListener(ContentProviderRegisterEvent::class, ContentProvider::class);
class ContentProvider implements IContentProvider {
// ...
public function handle(Event $event): void {
if (!$event instanceof ContentProviderRegisterEvent) {
return;
}
$event\->registerContentProvider('\*\*\*appId\*\*\*', '\*\*\*providerId\*\*\*', ContentProvider::class);
}
Any interaction with the content manager using the ContentManager’s methods or listing the providers in the Assistant should automatically register the provider.
You may call the `registerContentProvider` method explicitly if you want to trigger an initial import of content items.
### Submitting ContentItem data[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/context_chat.html#submitting-contentitem-data "Link to this heading")
Before submitting, you should check that the Context Chat app is enabled first by calling the `isContextChatAvailable()` method.
Then, to submit content, wrap it in a list of `\OCP\ContextChat\ContentItem` objects:
new ContentItem(
string $itemId,
string $providerId,
string $title,
string $content,
string $documentType,
\\DateTime $lastModified,
array $users,
)
Note
1. Ensure that item IDs are unique across all users for a given provider.
2. The app ID and provider ID both cannot contain double underscores, spaces, or colons.
3. The `documentType` is a natural language term for your document type in English, e.g. `E-Mail` or `Bookmark`.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# OCS API — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/index.html)
* OCS API
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/client_apis/OCS/index.rst)
* * *
OCS API[](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/index.html#ocs-api "Link to this heading")
================================================================================================================================
To browse the new OCS API documentation please go [here](https://docs.nextcloud.com/server/latest/developer_manual/_static/openapi.html)
.
The old documentation is still kept as it provides some additional documentation that is not completely covered in the new documentation:
* [OCS OpenAPI tutorial](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html)
* [Requirements and prerequisites](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#requirements-and-prerequisites)
* [Best practices](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#best-practices)
* [API design and consistency](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#api-design-and-consistency)
* [PREFER to expose your APIs using OCS](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#prefer-to-expose-your-apis-using-ocs)
* [CAREFULLY handle empty values in JSON Responses](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#carefully-handle-empty-values-in-json-responses)
* [DO use the same data structures for the same group of responses](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#do-use-the-same-data-structures-for-the-same-group-of-responses)
* [CONSIDER how your API will be used](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#consider-how-your-api-will-be-used)
* [Typing and documentation](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#typing-and-documentation)
* [DO type controller and helper methods as explicit as possible](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#do-type-controller-and-helper-methods-as-explicit-as-possible)
* [DO set all descriptions for parameters and methods](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#do-set-all-descriptions-for-parameters-and-methods)
* [Errors and headers](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#errors-and-headers)
* [DO NOT throw non-OCS\*Exceptions](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#do-not-throw-non-ocs-exceptions)
* [DO NOT use the `addHeader` (use `setHeaders`)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#do-not-use-the-addheader-use-setheaders)
* [Tips and tricks](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#tips-and-tricks)
* [Tutorial: How to add OpenAPI support to your OCS API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#tutorial-how-to-add-openapi-support-to-your-ocs-api)
* [Scopes](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#scopes)
* [Tags](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#tags)
* [Share type response definitions](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#share-type-response-definitions)
* [Handle exceptions](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#handle-exceptions)
* [Ignore certain endpoints](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#ignore-certain-endpoints)
* [Expose capabilities](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#expose-capabilities)
* [Generate the specification](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-openapi.html#generate-the-specification)
* [OCS APIs overview](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html)
* [Authentication](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#authentication)
* [Testing requests with curl](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#testing-requests-with-curl)
* [User metadata](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#user-metadata)
* [User metadata - List user IDs](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#user-metadata-list-user-ids)
* [Capabilities API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#capabilities-api)
* [Theming capabilities](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#theming-capabilities)
* [Direct Download](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#direct-download)
* [Notifications](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#notifications)
* [Auto-complete and user search](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#auto-complete-and-user-search)
* [Filtering the auto-complete results](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#filtering-the-auto-complete-results)
* [Force language for a given call](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-api-overview.html#force-language-for-a-given-call)
* [OCS Share API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html)
* [Local Shares](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#local-shares)
* [Get all Shares](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#get-all-shares)
* [Get Shares from a specific file or folder](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#get-shares-from-a-specific-file-or-folder)
* [Get information about a known Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#get-information-about-a-known-share)
* [Create a new Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#create-a-new-share)
* [Delete Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#delete-share)
* [Update Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#update-share)
* [Share attributes](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#share-attributes)
* [Download permission](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#download-permission)
* [File request](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#file-request)
* [Send email](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#send-email)
* [Federated Cloud Shares](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#federated-cloud-shares)
* [Create a new Federated Cloud Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#create-a-new-federated-cloud-share)
* [List accepted Federated Cloud Shares](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#list-accepted-federated-cloud-shares)
* [Get information about a known Federated Cloud Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#get-information-about-a-known-federated-cloud-share)
* [Delete an accepted Federated Cloud Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#delete-an-accepted-federated-cloud-share)
* [List pending Federated Cloud Shares](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#list-pending-federated-cloud-shares)
* [Accept a pending Federated Cloud Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#accept-a-pending-federated-cloud-share)
* [Decline a pending Federated Cloud Share](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-share-api.html#decline-a-pending-federated-cloud-share)
* [OCS Sharee API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-sharee-api.html)
* [Search](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-sharee-api.html#search)
* [Search sharees](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-sharee-api.html#search-sharees)
* [Recommendation](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-sharee-api.html#recommendation)
* [Sharee recommendations](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-sharee-api.html#sharee-recommendations)
* [OCS Status API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html)
* [User Status - Status Manipulation](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#user-status-status-manipulation)
* [Fetch your own status](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#fetch-your-own-status)
* [Set your own status](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#set-your-own-status)
* [Set a custom message (predefined)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#set-a-custom-message-predefined)
* [Set a custom message (user-defined)](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#set-a-custom-message-user-defined)
* [Clear message](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#clear-message)
* [User Status - Predefined statuses](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#user-status-predefined-statuses)
* [Fetch the list of predefined statuses](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#fetch-the-list-of-predefined-statuses)
* [User Status - Retrieve statuses](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#user-status-retrieve-statuses)
* [Fetch a list of all set user-statuses](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#fetch-a-list-of-all-set-user-statuses)
* [Fetch a specific user’s status](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#fetch-a-specific-user-s-status)
* [Fetch a user’s backup status](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#fetch-a-user-s-backup-status)
* [Files Sharing](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#files-sharing)
* [User status - Restore backup](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-status-api.html#user-status-restore-backup)
* [OCS Recommendations API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-recommendations-api.html)
* [Recommendations - Retrieval](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-recommendations-api.html#recommendations-retrieval)
* [Fetch user-controlled recommendations](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-recommendations-api.html#fetch-user-controlled-recommendations)
* [Fetch user setting and recommendations](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-recommendations-api.html#fetch-user-setting-and-recommendations)
* [OCS user preferences API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-user-preferences-api.html)
* [Setting a preference](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-user-preferences-api.html#setting-a-preference)
* [Setting multiple preference](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-user-preferences-api.html#setting-multiple-preference)
* [Deleting a preference](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-user-preferences-api.html#deleting-a-preference)
* [Deleting multiple preference](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-user-preferences-api.html#deleting-multiple-preference)
* [OCS Translation API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-translation-api.html)
* [Get available translation options](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-translation-api.html#get-available-translation-options)
* [Language tuple structure](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-translation-api.html#language-tuple-structure)
* [Translate a string](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-translation-api.html#translate-a-string)
* [OCS TextProcessing API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-textprocessing-api.html)
* [Get available task types](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-textprocessing-api.html#get-available-task-types)
* [Schedule a task](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-textprocessing-api.html#schedule-a-task)
* [Fetch a task by ID](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-textprocessing-api.html#fetch-a-task-by-id)
* [OCS Text-To-Image API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html)
* [Check availability](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html#check-availability)
* [Schedule a task](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html#schedule-a-task)
* [Fetch a task by ID](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html#fetch-a-task-by-id)
* [Fetch a result image](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html#fetch-a-result-image)
* [Delete a task](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html#delete-a-task)
* [List tasks by App](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-text2image-api.html#list-tasks-by-app)
* [OCS TaskProcessing API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-taskprocessing-api.html)
* [OCS Out-of-office API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-out-of-office-api.html)
* [Fetch ongoing data](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-out-of-office-api.html#fetch-ongoing-data)
* [Fetch upcoming or ongoing data](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-out-of-office-api.html#fetch-upcoming-or-ongoing-data)
* [Modify out-of-office data](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-out-of-office-api.html#modify-out-of-office-data)
* [Clear data and disable out-of-office](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-out-of-office-api.html#clear-data-and-disable-out-of-office)
* [OCS FullTextSearch Collection API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html)
* [Concept overview](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#concept-overview)
* [First steps](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#first-steps)
* [Installing the apps](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#installing-the-apps)
* [Initializing the collection](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#initializing-the-collection)
* [Linking a collection to a user account](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#linking-a-collection-to-a-user-account)
* [Using the collection OCS API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#using-the-collection-ocs-api)
* [Retrieving the list of document to be (re-)indexed](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#retrieving-the-list-of-document-to-be-re-indexed)
* [Get data and metadata from a document](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#get-data-and-metadata-from-a-document)
* [Set document as indexed](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#set-document-as-indexed)
* [Reset collection](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-fulltextsearch-collections-api.html#reset-collection)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Settings — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Settings
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/settings.rst)
* * *
Settings[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html#settings "Link to this heading")
====================================================================================================================================
* [Declarative settings](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html)
* [Registering settings schema](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#registering-settings-schema)
* [Class-based schema registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#class-based-schema-registration)
* [Event-based schema registration](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#event-based-schema-registration)
* [Handling settings storage](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#handling-settings-storage)
* [Internal storage type](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#internal-storage-type)
* [External storage type](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#external-storage-type)
* [Register get/set listeners](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#register-get-set-listeners)
* [Schema field types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#schema-field-types)
* [Basic input types](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#basic-input-types)
* [Checkbox and Multi-checkbox](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#checkbox-and-multi-checkbox)
* [Radio](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#radio)
* [Select and Multi-select](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#select-and-multi-select)
* [Sensitive field type](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#sensitive-field-type)
An app can register both admin settings as well as personal settings. Settings are divided into sections to group similar settings together. For example, in the **Sharing** section are only settings (built-in and of apps) related to sharing.
Settings form[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html#settings-form "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------
For the settings to show up, three things are necessary:
1. A class implementing `\OCP\Settings\ISettings`
2. A template
3. The implementing class specified in the app’s info.xml
Below is an example of an implementer of the ISettings interface. It is based on the survey\_client solution.
collector \= $collector;
$this\->config \= $config;
$this\->l \= $l;
$this\->dateTimeFormatter \= $dateTimeFormatter;
$this\->jobList \= $jobList;
}
/\*\*
\* @return TemplateResponse
\*/
public function getForm() {
$lastSentReportTime \= (int) $this\->config\->getAppValue('survey\_client', 'last\_sent', 0);
if ($lastSentReportTime \=== 0) {
$lastSentReportDate \= $this\->l\->t('Never');
} else {
$lastSentReportDate \= $this\->dateTimeFormatter\->formatDate($lastSentReportTime);
}
$lastReport \= $this\->config\->getAppValue('survey\_client', 'last\_report', '');
if ($lastReport !== '') {
$lastReport \= json\_encode(json\_decode($lastReport, true), JSON\_PRETTY\_PRINT);
}
$parameters \= \[\
'is\_enabled' \=> $this\->jobList\->has('OCA\\Survey\_Client\\BackgroundJobs\\MonthlyReport', null),\
'last\_sent' \=> $lastSentReportDate,\
'last\_report' \=> $lastReport,\
'categories' \=> $this\->collector\->getCategories()\
\];
return new TemplateResponse('yourappid', 'admin', $parameters);
}
/\*\*
\* The section ID, e.g. 'sharing'
\*
\* @return string
\*/
public function getSection() {
return 'survey\_client';
}
/\*\*
\* Whether the form should be rather on the top or bottom of
\* the admin section. The forms are arranged in ascending order of the
\* priority values. It is required to return a value between 0 and 100.
\*
\* @return int
\*/
public function getPriority() {
return 50;
}
}
The parameters of the constructor will be resolved and an instance created automatically on demand, so that the developer does not need to take care of it.
`getSection` is supposed to return the section ID of the desired admin section. Currently, built-in values are `server`, `sharing`, `encryption`, `logging`, `additional` and `tips-tricks`. Apps can register sections of their own (see below), and also register into sections of other apps.
`getPriority` is used to order forms within a section. The lower the value, the more on top it will appear, and vice versa. The result depends on the priorities of other settings.
Nextcloud will look for the templates in a template folder located in your app’s root directory. It should always end on .php, in this case `templates/admin.php` would be the final relative path.
t('Your app')); ?>
t('Only administrators are allowed to click the red button')); ?>
checked="checked" />
t('Things to define')); ?>
$data) {
?>
checked="checked" />
t('Last report')); ?>
t('Sent on: %s', \[$\_\['last\_sent'\]\])); ?>
Then, the implementing class should be added to the info.xml. Settings will be registered upon installation and update. When settings are added to an existing, installed, and enabled app, it should be made sure that the version is increased so Nextcloud can register the class. It is only possible to register one ISettings implementer.
For a more complex example using embedded templates have a look at the implementation of the **user\_ldap** app.
Section[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html#section "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------
It is also possible that an app registers its own section. This should be done only if there is no fitting corresponding section and the app’s settings form takes a lot of screen estate. Otherwise, register to “additional”.
Basically, it works the same way as with the settings form. There are only two differences. First, the interface that must be implemented is `\OCP\Settings\IIconSection`.
An example implementation of the IIconSection interface:
l \= $l;
$this\->urlGenerator \= $urlGenerator;
}
/\*\*
\* Returns the ID of the section. It is supposed to be a lowercase string
\*
\* @returns string
\*/
public function getID() {
return 'yourappid'; //or a generic id if feasible
}
/\*\*
\* Returns the translated name as it should be displayed, e.g. 'LDAP / AD
\* integration'. Use the L10N service to translate it.
\*
\* @return string
\*/
public function getName() {
return $this\->l\->t('Translatable Section Name');
}
/\*\*
\* Whether the form should be rather on the top or bottom of
\* the settings navigation. The sections are arranged in ascending order of
\* the priority values. It is required to return a value between 0 and 99.
\*
\* @return int
\*/
public function getPriority() {
return 80;
}
/\*\*
\* The relative path to an icon describing the section
\*
\* @return string
\*/
public function getIcon() {
return $this\->urlGenerator\->imagePath('yourapp', 'icon.svg');
}
}
Also, the section must be registered in the app’s info.xml.
Registering Settings and Sections[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html#registering-settings-and-sections "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
As mentioned already both Settings and Sections should be registered in the info.xml of your app This is rather straightforward as you can see in the code snippet below
...
OCA\\YourAppNamespace\\Settings\\AdminOCA\\YourAppNamespace\\Settings\\AdminSectionOCA\\YourAppNamespace\\Settings\\PersonalOCA\\YourAppNamespace\\Settings\\PersonalSection
...
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Speech-To-Text — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Speech-To-Text
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/speech-to-text.rst)
* * *
Speech-To-Text[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#speech-to-text "Link to this heading")
======================================================================================================================================================
Added in version 27.
Deprecated since version 30: Use the TaskProcessing API instead
Nextcloud offers a **Speech-To-Text** API. The overall idea is that there is a central OCP API that apps can use to request transcriptions of audio or video files. To be technology agnostic any app can provide this Speech-To-Text functionality by registering a Speech-To-Text provider.
Consuming the Speech-To-Text API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#consuming-the-speech-to-text-api "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To consume the Speech-To-Text API, you will need `\OCP\SpeechToText\ISpeechToTextManager`. This manager offers the following methods:
> * `hasProviders()` This method returns a boolean which indicates if any providers have been registered. If this is false you cannot use Speech-To-Text.
>
> * `transcribeFile(File $file)` This method takes a `OCP\Files\File` Object which should point to a media file and will attempt to transcribe it **in the current process**. It will thus block until transcription has finished and will return the transcript as a string. Using this method is thus only recommend in CLI commands or Background Jobs when you are not limited by any HTTP request timeouts and execution time limits.
>
> * `scheduleFileTranscription(File $file, ?string $userId, string $appId)` This method schedules a transcription of the passed media file **in a background job** and will thus not block.
>
### Listening to the transcription events[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#listening-to-the-transcription-events "Link to this heading")
Since `scheduleFileTranscription` does not block, you will need to listen to the following events in your app to obtain the transcript or be notified of any failure.
> * `OCP\SpeechToText\Events\TranscriptionSuccessfulEvent` This event class offers the `getTranscript()` method which returns the transcript as a string
>
> * `OCP\SpeechToText\Events\TranscriptionFailedEvent` This event class offers the `getErrorMessage()` method which returns the error message as a string (only in English and for debugging purposes, so don’t show this to the user)
>
Both classes provide the `$appId` and `$userId` params that you initially passed to `scheduleFileTranscription` via `getAppId()` and `getUserId()` as well as `getFileId()` and `getFile()` to access the media file that was transcribed.
For example, in your `lib/AppInfo/Application.php` file:
$context\->registerEventListener(OCP\\SpeechToText\\Events\\TranscriptionSuccessfulEvent::class, MyTranscriptionListener::class);
$context\->registerEventListener(OCP\\SpeechToText\\Events\\TranscriptionFailedEvent::class, MyTranscriptionListener::class);
The corresponding `MyReferenceListener` class can look like:
getAppId() !== Application::APP\_ID) {
return;
}
if ($event instanceof TranscriptionSuccessfulEvent) {
$transcript \= $event\->getTranscript();
// store $transcript somewhere
}
if ($event instanceof TranscriptionFailedEvent) {
$error \= $event\->getErrorMessage();
$userId \= $event\->getUserId();
// Notify relevant user about failure
}
}
}
Implementing a Speech-To-Text provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#implementing-a-speech-to-text-provider "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A **Speech-To-Text provider** is a class that implements the interface `OCP\SpeechToText\ISpeechToTextProvider`.
l\->t('My awesome speech to text provider');
}
public function transcribeFile(File $file): string {
// transcribe file here and return transcript
}
}
The method `getName` returns a string to identify the registered provider in the user interface.
The method `transcribeFile` transcribes the passed file and returns the transcript. In case transcription fails, you should throw a `RuntimeException` with an explanatory error message.
The class would typically be saved into a file in `lib/SpeechToText` of your app but you are free to put it elsewhere as long as it’s loadable by Nextcloud’s [dependency injection container](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
.
Provider with user context[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#provider-with-user-context "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Added in version 29.0.0.
Sometimes the processing of a the task may depend upon which user requested the task. You can now obtain this information in your provider by additionally implementing the `OCP\SpeechToText\ISpeechToTextProviderWithUserId` interface:
l\->t('My awesome speech to text provider');
}
public function setUserId(?string $userId): void { $this\->userId \= $userId; }
public function transcribeFile(File $file): string {
// transcribe file here with the use of $this->userId context and return transcript
}
}
Provider registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#provider-registration "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
The provider class is registered via the [bootstrap mechanism](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
of the `Application` class.
registerSpeechToTextProvider(Provider::class); }
public function boot(IBootContext $context): void {}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Two-factor providers — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Two-factor providers
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/two-factor-provider.rst)
* * *
Two-factor providers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#two-factor-providers "Link to this heading")
=======================================================================================================================================================================
Two-factor auth providers apps are used to plug custom second factors into the Nextcloud core.
Implementing a simple two-factor auth provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#implementing-a-simple-two-factor-auth-provider "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Two-factor auth providers must implement the [OCP\\Authentication\\TwoFactorAuth\\IProvider](https://github.com/nextcloud/server/blob/master/lib/public/Authentication/TwoFactorAuth/IProvider.php)
interface. The example below shows a minimalistic example of such a provider.
OCA\\TwoFactor\_Test\\Provider\\TwoFactorTestProvider
Providing an icon (optional)[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#providing-an-icon-optional "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To enhance how a provider is shown in the list of selectable providers on the login page, an icon can be specified. For that the provider class must implement the [IProvidesIcons](https://github.com/nextcloud/server/blob/master/lib/public/Authentication/TwoFactorAuth/IProvidesIcons.php)
interface. The light icon will be used on the login page, whereas the dark one will be placed next to the heading of the optional personal settings (see below).
Provide personal settings (optional)[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#provide-personal-settings-optional "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Like other Nextcloud apps, two-factor providers often require user configuration to work. In Nextcloud 15 a new, consolidated two-factor settings section was added. To add personal provider settings there, a provider must implement the [IProvidesPersonalSettings](https://github.com/nextcloud/server/blob/master/lib/public/Authentication/TwoFactorAuth/IProvidesPersonalSettings.php)
interface.
Make a provider activatable by the admin (optional)[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#make-a-provider-activatable-by-the-admin-optional "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In order to make it possible for an admin to enable the provider for a given user via the occ command line tool, it’s necessary to implement the [OCP\\Authentication\\TwoFactorAuth\\IActivatableByAdmin](https://github.com/nextcloud/server/blob/master/lib/public/Authentication/TwoFactorAuth/IActivatableByAdmin.php)
interface. As described in the linked interface documentation, this should only be implemented for providers that need no user interaction when activated.
Make a provider deactivatable by the admin (optional)[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/two-factor-provider.html#make-a-provider-deactivatable-by-the-admin-optional "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In order to make it possible for an admin to disable the provider for a given user via the occ command line tool, it’s necessary to implement the [OCP\\Authentication\\TwoFactorAuth\\IDeactivatableByAdmin](https://github.com/nextcloud/server/blob/master/lib/public/Authentication/TwoFactorAuth/IDeactivatableByAdmin.php)
interface. As described in the linked interface documentation, this should only be implemented for providers that need no user interaction when deactivated.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Task Processing — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Task Processing
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/task_processing.rst)
* * *
Task Processing[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#task-processing "Link to this heading")
=========================================================================================================================================================
Added in version 30.0.0.
Nextcloud offers a **Task Processing** API which replaces the previously introduced [Text Processing](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text_processing.html#text-processing)
, [TextToImage](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/text2image.html#text2image)
and [Speech-To-Text](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/speech-to-text.html#speech-to-text)
APIs. The overall idea is that there is a central OCP API that apps can use to schedule all kinds of tasks (mainly intended for AI tasks). To be technology agnostic any other app can provide this task functionality by registering Task Processing providers for specific Task types.
Consuming the Task Processing API[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#consuming-the-task-processing-api "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To consume the Task Processing API, you will need to [inject](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
`\OCP\TaskProcessing\IManager`. This manager offers the following methods:
> * `hasProviders()` This method returns a boolean which indicates if any providers have been registered. If this is false you cannot use the TextProcessing feature.
>
> * `getAvailableTaskTypes(bool $showDisabled = false)` This method returns an array of enabled task types indexed by their ID with their names and additional metadata. If you set `$showdisabled` to `true` (available since NC31), it will include disabled task types. Since NC33 this will also include the `isInternal` field that signifies whether the task type is user-facing or intended for internal use only.
>
> * `getAvailableTaskTypeIds()` This method (available since NC32) returns a list of available task type IDs. It uses the same logic as `getAvailableTaskTypes()` but is faster because it does not compute the task types metadata (which can be slow when getting default field values or multiselect value lists). If you just want to check if a feature is available, prefer using this method rather than `getAvailableTaskTypes()`.
>
> * `scheduleTask(Task $task)` This method provides the actual scheduling functionality. The task is defined using the Task class. This method runs the task asynchronously in a background job.
>
> * `getTask(int $id)` This method fetches a task specified by its id.
>
> * `deleteTask(Task $task)` This method deletes a task
>
> * `cancelTask(int $id)` This method cancels a task specified by its id.
>
If you would like to use the task processing functionality in a client, there are also OCS endpoints available for this: [OCS Task Processing API](https://docs.nextcloud.com/server/latest/developer_manual/client_apis/OCS/ocs-taskprocessing-api.html#ocs-taskprocessing-api)
### Tasks types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#tasks-types "Link to this heading")
The following built-in task types are available:
> * `'core:text2text'`: This task allows passing an arbitrary prompt to the language model. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToText`
>
> * Input shape:
>
> * `input`: `Text`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2text:chat'`: This task allows chatting with the language model. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextChat`
>
> * Input shape:
>
> * `system_prompt`: `Text`
>
> * `input`: `Text`
>
> * `history`: `ListOfTexts`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2text:chatwithtools'`: This task allows chatting with the language model with tools calling support. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextChatWithTools`
>
> * Input shape:
>
> * `system_prompt`: `Text`
>
> * `input`: `Text`
>
> * `tool_message`: `Text` A string containing a JSON array of `{"name": string, "content": string, "tool_call_id": string}`
>
> * `history`: `ListOfTexts` Each list item is a JSON string with `{"role": "human", "content": string}` or `{"role": "assistant", "content": string, (optional: "tool_calls": array<{"name": string, "type": "tool_call", "id": string, "args": object}>)}` or `{"role": "tool", "content": string, "name": string, "tool_call_id": string}`
>
> * `tools`: `Text` The tools parameter should be a JSON array formatted according to the OpenAI API specifications: [https://platform.openai.com/docs/api-reference/chat/create#chat-create-tools](https://platform.openai.com/docs/api-reference/chat/create#chat-create-tools)
>
>
> * Output shape:
>
> * `output`: `Text`
>
> * `tool_calls`: `Text` A string containing a JSON array with `{"name": string, "type": "tool_call", "id": string, "args": object}`
>
>
>
> * `'core:contextagent:interaction'`: This task allows chatting with an agent. It is implemented by `\OCP\TaskProcessing\TaskTypes\ContextAgentInteraction`
>
> * Input shape:
>
> * `input`: `Text`
>
> * `confirmation`: `Number` Boolean integer indicating whether to confirm previously requested actions: 0 to reject or 1 to confirm.
>
> * `conversation_token`: `Text` Token representing the conversation
>
>
> * Output shape:
>
> * `output`: `Text`
>
> * `conversation_token`: `Text`
>
> * `actions`: `Text`
>
>
>
> * `'core:text2text:formalization'`: This task will reformulate the passed input text to be more formal in tone. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextFormalization`
>
> * Input shape:
>
> * `input`: `Text`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2text:headline'`: This task will generate a headline for the passed input text. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextHeadline`
>
> * Input shape:
>
> * `input`: `Text`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2text:reformulation'`: This task will reformulate the passed input text arbitrarily. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextReformulation`
>
> * Input shape:
>
> * `input`: `Text`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2text:simplification'`: This task will reformulate the passed input text to be very easy to understand, e.g. by children. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextSimplification`
>
> * Input shape:
>
> * `input`: `Text`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2text:summary'`: This task will summarize the passed input text. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextSummary`
>
> * Input shape: \* `input`: `Text`
>
> * Output shape: \* `output`: `Text`
>
>
> * `'core:text2text:topics'`: This task will generate a comma-separated list of topics for the passed input text. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextTopics`
>
> * Input shape: \* `input`: `Text`
>
> * Output shape: \* `output`: `Text`
>
>
> * `'core:text2text:translate'`: This task will translate text from one language to another. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextTranslate`
>
> * Input shape: \* `input`: `Text` \* `origin_language`: `Enum` \* `target_language`: `Enum`
>
> * Output shape: \* `output`: `Text`
>
>
> * `'core:audio2text'`: This task type is for transcribing audio to text. It is implemented by `\OCP\TaskProcessing\TaskTypes\AudioToText`
>
> * Input shape:
>
> * `input`: `Audio`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2image'`: This task type is for generating images from text prompts. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToImage`
>
> * Input shape:
>
> * `input`: `Text`
>
> * `numberOfImages`: `Number`
>
>
> * Output shape:
>
> * `output`: `ListOfImages`
>
>
>
> * `'core:text2text:changetone'`: This task type is for reformulating a text, changing its tone. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextChangeTone`
>
> * Input shape:
>
> * `input`: `Text`
>
> * `tone`: `Enum`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2text:proofread'`: This task type is for proofreading a text, checking it for grammar and spelling mistakes. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToTextProofread`
>
> * Input shape:
>
> * `input`: `Text`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:text2speech'`: This task type is for generating speech from text prompts. It is implemented by `\OCP\TaskProcessing\TaskTypes\TextToSpeech`
>
> * Input shape:
>
> * `input`: `Text`
>
>
> * Output shape:
>
> * `speech`: `Audio`
>
>
>
> * `'core:analyze-images'`: This task type is for analyzing images. It is implemented by `\OCP\TaskProcessing\TaskTypes\AnalyzeImages`
>
> * Input shape:
>
> * `input`: `Text`
>
> * `images`: `ListOfImages`
>
>
> * Output shape:
>
> * `output`: `Text`
>
>
>
> * `'core:image2text:ocr'`: This task type is for extracting text from files using OCR. It is implemented by `\OCP\TaskProcessing\TaskTypes\ImageToTextOpticalCharacterRecognition`
>
> * Input shape:
>
> * `input`: `ListOfFiles`
>
>
> * Output shape:
>
> * `output`: `ListOfTexts`
>
>
>
Task types can be disabled in the AI admin settings so they are not available for the Assistant or other apps even if they are implemented. All implemented Task types are enabled by default.
#### LLM Prompts and multilingual I/O[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#llm-prompts-and-multilingual-i-o "Link to this heading")
When writing prompts for the TextToText task type in your apps, we recommend testing it with at least
* OpenAI GPT-3.5
* Llama 3.1
Also, make sure that you instruct the model to use the correct language in its output. By default most models will answer in English if the main prompt is in English, even though the source data is in another language. A tweak to make sure of this is to instruct the model as follows:
"Detect the language used in the text and make sure to answer in the same language without mentioning the language explicitly."
##### Input and output shapes[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#input-and-output-shapes "Link to this heading")
Each task type defines how its input and output should look. This is called the input and output shape.
For example the TextToImage type defines its input shape as follows:
/\*\*
\* @return ShapeDescriptor\[\]
\* @since 30.0.0
\*/
public function getInputShape(): array {
return \[\
'input' \=> new ShapeDescriptor(\
$this\->l\->t('Prompt'),\
$this\->l\->t('Describe the image you want to generate'),\
EShapeType::Text\
),\
'numberOfImages' \=> new ShapeDescriptor(\
$this\->l\->t('Number of images'),\
$this\->l\->t('How many images to generate'),\
EShapeType::Number\
),\
\];
}
The task input and output are always represented by an associative array. In this case, the task input for TextToImage must have an array key named `'input'` which must contain a text and an array key named `'numberOfImages'` which must contain a number.
If you want to simply use a task type, you can look up it’s input and output shapes above or, if it is not built-in, in the documentation or implementation of the app introducing the task type. If you would like to use task types dynamically without knowing their shapes in advance, you can get their shape information from the `IManager#getAvailableTaskTypes()` method. The ShapeDescriptor class allows accessing the type data as well as human readable name and description using the `getName()`, `getDescription()` and `getShapeType()` methods.
##### Shape types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#shape-types "Link to this heading")
Input and output shape keys can have one of a pre-defined set of types, which are enumerated in the `\OCP\TaskProcessing\EShapeType` Enum:
enum EShapeType: int {
case Number \= 0;
case Text \= 1;
case Image \= 2;
case Audio \= 3;
case Video \= 4;
case File \= 5;
case Enum \= 6;
case ListOfNumbers \= 10;
case ListOfTexts \= 11;
case ListOfImages \= 12;
case ListOfAudio \= 13;
case ListOfVideo \= 14;
case ListOfFiles \= 15;
}
When consuming the task processing API, `Image`, `Audio`, `Video` and `File` slots are filled with Nextcloud file IDs, so instead of supplying the image data directly as a string to the task you create a file for it and pass the id. Similarly, if the task outputs an image, you will receive a file ID in that slot.
### Tasks[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#tasks "Link to this heading")
To create a task we use the `\OCP\TaskProcessing\Task` class. Its constructor takes the following arguments: `new \OCP\TaskProcessing\Task(string $taskTypeId, array $input, string $appId, ?string $userId, string $customId = '')`. For example:
// getAvailableTaskTypeIds is faster than getAvailableTaskTypes
// if (isset($textprocessingManager->getAvailableTaskTypes()\[TextToTextSummary::ID\]) {
// if you don't need the task type metadata, prefer this:
if (in\_array(TextToTextSummary::ID, $textprocessingManager\->getAvailableTaskTypeIds(), true) {
$summaryTask \= new Task(TextToTextSummary::ID, $emailText, "my\_app", $userId, (string) $emailId);
} else {
// cannot use summarization
}
The task class objects have the following methods available:
> * `getTaskTypeId()` This returns the task type.
>
> * `getStatus()` This method returns one of the below statuses.
>
> * `getId()` This method will return `null` before the task has been passed to `scheduleTask` otherwise it will return the unique ID of the task.
>
> * `getInput()` This returns the input array.
>
> * `getOutput()` This method will return `null` unless the task was successfully run, in that case it will return the output array
>
> * `getAppId()` This returns the originating application ID of the task.
>
> * `getCustomId()` This returns the original scheduler-defined identifier for the task
>
> * `getUserId()` This returns the originating user ID of the task.
>
> * `getCompletionExpectedAt()` This is available after scheduling the task and returns the DateTime when the task is expected to be completed
>
> * `getLastUpdated()` This returns the time the task was last updated as a unix timestamp
>
> * `getScheduledAt()` This returns the time the task was scheduled as a unix timestamp
>
> * `getStartedAt()` This returns the time the task execution started as a unix timestamp
>
> * `getEndedAt()` This returns the time the task execution ended as a unix timestamp
>
> * `getErrorMessage()` This returns the error message if the task execution failed
>
> * `getProgress()` This returns the current task progress, between 0 and 1 while the task is running. Will be 1 when the task is completed
>
> * `setWebhookUri()` This sets the URI of a webhook that will be notified when the task execution has ended
>
> * `setWebhookMethod()` This sets the HTTP method that will be used for the webhook when the task execution has ended
>
> * `getWebhookUri()` This returns the webhook URI that will be notified when the task execution has ended
>
> * `getWebhookMethod()` This returns the HTTP method that will be used for the webhook when the task execution has ended
>
Added in version 33.0.0:
* `getUserFacingErrorMessage()` This returns any error message that is meant to be displayed to the user, even if a task has failed, this is not guaranteed to be set.
You could now schedule the task as follows:
try {
$taskprocessingManager\->scheduleTask($summaryTask);
} catch (OCP\\TaskProcessing\\Exception\\Exception|OCP\\TaskProcessing\\Exception\\PreConditionNotMetException|OCP\\TaskProcessing\\Exception\\UnauthorizedException|OCP\\TaskProcessing\\Exception\\ValidationException $e) {
// scheduling task failed
}
### Task statuses[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#task-statuses "Link to this heading")
All tasks always have one of the below statuses:
Task::STATUS\_CANCELLED \= 5;
Task::STATUS\_FAILED \= 4;
Task::STATUS\_SUCCESSFUL \= 3;
Task::STATUS\_RUNNING \= 2;
Task::STATUS\_SCHEDULED \= 1;
Task::STATUS\_UNKNOWN \= 0;
### Listening to the task processing events[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#listening-to-the-task-processing-events "Link to this heading")
Since `scheduleTask` does not block, you will need to listen to the following events in your app to obtain the output or be notified of any failure.
> * `OCP\TaskProcessing\Events\TaskSuccessfulEvent` This event class offers the `getTask()` method which returns the up-to-date task object, with the task output.
>
> * `OCP\TaskProcessing\Events\TaskFailedEvent` In addition to the `getTask()` method, this event class provides the `getErrorMessage()` method which returns the error message as a string (only in English and for debugging purposes, so don’t show this to the user)
>
For example, in your `lib/AppInfo/Application.php` file:
$context\->registerEventListener(OCP\\TaskProcessing\\Events\\TaskSuccessfulEvent::class, MyPromptResultListener::class);
$context\->registerEventListener(OCP\\TaskProcessing\\Events\\TaskFailedEvent::class, MyPromptResultListener::class);
The corresponding `MyPromptResultListener` class can look like:
getTask()\->getAppId() !== Application::APP\_ID) {
return;
}
if ($event instanceof TaskSuccessfulEvent) {
$output \= $event\->getTask()\->getOutput()
// store $output somewhere
}
if ($event instanceof TaskFailedEvent) {
$error \= $event\->getErrorMessage()
$userId \= $event\->getTask()\->getUserId()
// Notify relevant user about failure
}
}
}
Implementing a TaskProcessing provider[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#implementing-a-taskprocessing-provider "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A **Task processing provider** will usually be a class that implements the interface `OCP\TaskProcessing\ISynchrounousProvider`.
l\->t('My awesome summary provider');
}
public function getTaskTypeId(): string {
return TextToTextSummary::ID;
}
public function process(?string $userId, array $input, callable $reportProgress): array {
// Return the output here
}
public function getExpectedRuntime(): int {
// usually takes 1min on average
return 60;
}
public function getInputShapeDefaults(): array {
return \[\];
}
public function getOptionalInputShape(): array {
return \[\];
}
public function getOptionalInputShapeDefaults(): array {
return \[\];
}
public function getOptionalOutputShape(): array {
return \[\];
}
public function getInputShapeEnumValues(): array {
return \[\];
}
public function getOptionalInputShapeEnumValues(): array {
return \[\];
}
public function getOutputShapeEnumValues(): array {
return \[\];
}
public function getOptionalOutputShapeEnumValues(): array {
return \[\];
}
}
The method `getName` returns a string to identify the registered provider in the user interface.
The method `process` implements the task processing step. In case execution fails for some reason, you should throw a `\OCP\TaskProcessing\Exception\ProcessingException` with an explanatory error message. Since v33.0.0 you can now also throw an `OCP\TaskProcessing\Exception\UserFacingProcessingException` which includes a string parameter to set for error messages that will be propagated to the end-user, make sure to always translate these into the language of the user that requested the task. The rule of thumb of when to use a user-facing error message, is as follows: When the error happened due to a mistake from the user or the user can do something to fix the error, throw a user facing error. However, do make sure to not include implementation or server details in the user facing error message, that’s what the normal error message is for; it will only be visible to administrators.
Important to note here is that `Image`, `Audio`, `Video` and `File` slots in the input array will be filled with `\OCP\Files\File` objects for your convenience. When outputting one of these you should simply return a string, the API will turn the data into a proper file for convenience. The `$reportProgress` parameter is a callback that you may use at will to report the task progress as a single float value between 0 and 1. Its return value will indicate if the task is still running (`true`) or if it was cancelled (`false`) and processing should be terminated.
This class would typically be saved into a file in `lib/TaskProcessing` of your app but you are free to put it elsewhere as long as it’s loadable by Nextcloud’s [dependency injection container](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
.
### Providing additional inputs and outputs[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#providing-additional-inputs-and-outputs "Link to this heading")
Built-in task types often only specify the most basic input and output slots. If you would like to offer more input options with your provider you can specify optional inputs and outputs using the `getOptionalInputShape` and `getOptionalOutputShape` methods. You will need to return an associative array of `\OCP\TaskProcessing\ShapeDescriptor` objects.
public function getOptionalInputShape(): array {
return \[\
'tone' \=> new ShapeDescriptor($this\->l\->t('Tone of voice'), $this\->l\->t('Set the tone of voice to be used for the output'), EShapeType::Text)\
\];
}
In the same vein you can also provide optional output shape slots in addition to the pre-defined output slots.
public function getOptionalOutputShape(): array {
return \[\
'co2\_emissions' \=> new ShapeDescriptor($this\->l\->t('CO2 Emissions'), $this\->l\->t('The CO2 emissions produced by running this task in metric tons'), EShapeType::Number)\
\];
}
### Providing input defaults[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#providing-input-defaults "Link to this heading")
With the method `getInputShapeDefaults` you can specify default values for input slots (which are defined by the task type). For example:
public function getInputShapeDefaults(): array {
return \[\
'input' \=> 'There was once a man with many cows who wanted to have even more cows.'\
\];
}
Note that you can only specify default values for ‘Text’ and ‘Number’ slots.
The same works for your optional input shapes that you defined in `getOptionalInputShape`:
public function getOptionalInputShapeDefaults(): array {
return \[\
'tone' \=> 'Formal'\
\];
}
### Working with Enum shape types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#working-with-enum-shape-types "Link to this heading")
Both input and output shapes as well as the optional input and output shapes allow declaring slots of type `'Enum'`. An Enum is a type that only allows values from a pre-defined set. In the case of the TaskProcessing API this set is not defined by the task type, but by the provider implementing the task type using `getInputShapeEnumValues`, `getOutputShapeEnumValues`, `getOptionalInputShapeEnumValues` and `getOptionalOutputShapeEnumValues`.
You could, for example, implement the above tone of voice slot using an Enum:
public function getOptionalInputShape(): array {
return \[\
'tone' \=> new ShapeDescriptor($this\->l\->t('Tone of voice'), $this\->l\->t('Set the tone of voice to be used for the output'), EShapeType::Enum)\
\];
}
public function getOptionalInputShapeEnumValues(): array {
return \[\
'tone' \=> \[\
new ShapeEnumValue($this\->l\->t('Simple'), 'So that a kid could understand'),\
new ShapeEnumValue($this\->l\->t('Funny'), 'Funny'),\
new ShapeEnumValue($this\->l\->t('Formal'), 'Formal'),\
\]\
\];
}
### Providing more task types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#providing-more-task-types "Link to this heading")
If you would like to implement providers that handle additional task types, you can create your own Task type classes implementing the `OCP\TaskProcessing\ITaskType` interface:
new ShapeDescriptor('Audio', 'The audio', EShapeType::Audio),\
\];
}
public function getOutputShape(): array {
return \[\
'spectrogram' \=> new ShapeDescriptor('Spectrogram', 'The audio spectrogram', EShapeType::Image),\
\];
}
}
#### Internal task types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#internal-task-types "Link to this heading")
Added in version 33.0.0.
Other apps and clients will assume that task types are user-facing and will display them on the frontend. If your custom task types are not intended to be shown to users, you should implement the `IInternalTaskType` interface instead. This will make sure that other apps and clients know not to show your custom task type to end users.
### Triggerable providers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#triggerable-providers "Link to this heading")
Added in version 33.0.0.
Synchronous providers are executed automatically by a background job that will usually be targeted by a worker to make sure that it runs almost instantly. ExApps on the other hand used to have to poll the server for new tasks. Since the introduction of triggerable providers ExApps are now notified immediately of new tasks when they are scheduled. This is implemented via the `ITriggerableProvider` interface, which adds an additional `trigger(): void` method to the provider interface which is called when a new task is scheduled for this provider and there are no running tasks for it at the moment. Usually if you implement a provider in PHP you will not have to deal with this interface but it is documented here for completeness.
Provider and task type registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/task_processing.html#provider-and-task-type-registration "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Providers and task types are registered via the [bootstrap mechanism](https://docs.nextcloud.com/server/latest/developer_manual/app_development/bootstrap.html#bootstrapping)
of the `Application` class.
registerTaskProcessingProvider(Provider::class); $context\->registerTaskProcessingTaskType(AudioToImage::class); }
public function boot(IBootContext $context): void {}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# User Status — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* User Status
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/status.rst)
* * *
User Status[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/status.html#user-status "Link to this heading")
========================================================================================================================================
Nextcloud allows user to publish their current status. The status is then available in various part of the user interface (e.g. participants list in a Talk room).
Query Status[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/status.html#query-status "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------
Using the OCP\\UserStatus\\IManager interface, it is possible to query the user status, for a group of users.
statusManager \= $statusManager;
}
/\*\*
\* @param string\[\] $userIds
\* @return IUserStatus\[\]
\*/
public function queryStatusForUsers(array $userIds): array {
return $this\->statusManager\->getUserStatuses($userIds);
}
}
Updating the status programmatically[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/status.html#updating-the-status-programmatically "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A Nextcloud application can change the user status programmatically. This feature setUserStatus from the OCP\\UserStatus\\IManager interface when for example an user execute an action in the UI.
If the status is supposed to be reverted with an upcoming action from the user, setUserStatus will require to be called with $createBackup = true.
This then can be reverted with a call to revertUserStatus with the same $messageId and $status.
statusManager \= $statusManager;
}
public static function register(IEventDispatcher $dispatcher): void {
$dispatcher\->addListener(MyEvents::COOL\_EVENT\_STARTED, static function (CoolStartEvent $event) {
/\*\* @var self $listener \*/
$listener \= \\OC::$server\->get(self::class);
$listener\->setUserStatus($event);
});
$dispatcher\->addListener(MyEvents::COOL\_EVENT\_FINISHED, static function (CoolEndEvent $event) {
/\*\* @var self $listener \*/
$listener \= \\OC::$server\->get(self::class);
$listener\->revertUserStatus($event);
});
}
public function setUserStatus(ModifyParticipantEvent $event): void {
$this\->statusManager\->setUserStatus($event\->getUserId(), 'meeting', IUserStatus::AWAY, true);
}
public function revertUserStatus(ModifyParticipantEvent $event): void {
$this\->statusManager\->revertUserStatus($event\->getUserId(), 'meeting', IUserStatus::AWAY);
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Working with time — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* Working with time
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/time.rst)
* * *
Working with time[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/time.html#working-with-time "Link to this heading")
==================================================================================================================================================
You can inject the `\OCP\AppFramework\Utility\ITimeFactory` which wraps commonly used time functions for easier testability.
Methods[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/time.html#methods "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------
The factory extends the `\PSR\Clock\ClockInterface` with the following methods:
userManager \= $userManager; }
public function createUser($userId, $password) {
return $this\->userManager\->create($userId, $password);
}
}
Creating users[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#creating-users "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------
Creating a user is done by passing a username and password to the create method:
lib/Service/UserService.php[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#id2 "Link to this code")
userManager \= $userManager;
}
public function create($userId, $password) {
return $this\->userManager\->create($userId, $password); }
}
Modifying users[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#modifying-users "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
Users can be modified by getting a user by the userId or by a search pattern. The returned user objects can then be used to:
* Delete them
* Set a new password
* Disable/Enable them
* Get their home directory
userManager \= $userManager;
}
public function delete($userId) {
return $this\->userManager\->get($userId)\->delete(); }
// recoveryPassword is used for the encryption app to recover the keys
public function setPassword($userId, $password, $recoveryPassword) {
return $this\->userManager\->get($userId)\->setPassword($password, $recoveryPassword);
}
public function disable($userId) {
return $this\->userManager\->get($userId)\->setEnabled(false);
}
public function getHome($userId) {
return $this\->userManager\->get($userId)\->getHome();
}
}
User session information[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#user-session-information "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------
To login, logout or getting the currently logged in user, the IUserSession service that can be [injected](https://docs.nextcloud.com/server/latest/developer_manual/basics/dependency_injection.html#id2)
.
lib/Service/UserService.php[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#id3 "Link to this code")
userSession \= $userSession;
}
}
Then users can be logged in and out by using:
lib/Service/UserService.php[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#id4 "Link to this code")
userSession \= $userSession;
}
public function login(string $userId, string $password): void {
return $this\->userSession\->login($userId, $password); }
public function logout(): void {
$this\->userSession\->logout(); }
}
User objects[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#user-objects "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------
User objects can be acquired from the `IUserManager::get` method.
lib/Service/UserService.php[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#id5 "Link to this code")
userManager \= $userManager;
}
public function foo(string $userId): void {
/\*\* @var IUser|null $user \*/
$user \= $this\->userManager\->get($userId); if ($user !== null) {
// User exists
} else {
// The user does not exist
}
}
}
### User managers[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#user-managers "Link to this heading")
Added in version 27.
Nextcloud users can be defined as managers of other users. This is an informational property and has no influence on authorization. A user manager is not to confuse with admins or sub admins.
lib/Service/UserService.php[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/users.html#id6 "Link to this code")
userManager \= $userManager;
}
public function updateUserManagers(string $userId): void {
/\*\* @var IUser|null $user \*/
$user \= $this\->userManager\->get('user123');
if ($user \=== null) {
throw \\InvalidArgumentException("User $userId does not exist");
}
$managerUids \= $user\->getManagerUids(); // Turn UIDs into user objects
$managers \= array\_map(function(string $uid) {
return $this\->userManager\->get($uid);
}, $managerUids));
// Remove and managers that no longer exist as user
$existingManagers \= array\_filter($managers);
$user\->setManagerUids(array\_map(function(IUser $admin) { return $user\->getUID(); }, $existingManagers)); }
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/#)
* Nextcloud developer documentation
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/index.rst)
* * *
Nextcloud developer documentation[](https://docs.nextcloud.com/server/31/developer_manual/#nextcloud-developer-documentation "Link to this heading")
======================================================================================================================================================
Table of contents[](https://docs.nextcloud.com/server/31/developer_manual/#table-of-contents "Link to this heading")
----------------------------------------------------------------------------------------------------------------------
* [Prologue](https://docs.nextcloud.com/server/31/developer_manual/prologue/index.html)
* [Code of conduct](https://docs.nextcloud.com/server/31/developer_manual/prologue/code-of-conduct.html)
* [Help and communication](https://docs.nextcloud.com/server/31/developer_manual/prologue/help_communication.html)
* [Bugtracker](https://docs.nextcloud.com/server/31/developer_manual/prologue/bugtracker/index.html)
* [Security guidelines](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html)
* [Compatibility with the app ecosystem](https://docs.nextcloud.com/server/31/developer_manual/prologue/compatibility_app_ecosystem.html)
* [Getting started](https://docs.nextcloud.com/server/31/developer_manual/getting_started/index.html)
* [Development process](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html)
* [Development environment](https://docs.nextcloud.com/server/31/developer_manual/getting_started/devenv.html)
* [Coding style & general guidelines](https://docs.nextcloud.com/server/31/developer_manual/getting_started/coding_standards/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/31/developer_manual/basics/index.html)
* [Request lifecycle](https://docs.nextcloud.com/server/31/developer_manual/basics/request_lifecycle.html)
* [Routing](https://docs.nextcloud.com/server/31/developer_manual/basics/routing.html)
* [Dependency injection](https://docs.nextcloud.com/server/31/developer_manual/basics/dependency_injection.html)
* [Controllers](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html)
* [Middlewares](https://docs.nextcloud.com/server/31/developer_manual/basics/middlewares.html)
* [Events](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html)
* [Front-end](https://docs.nextcloud.com/server/31/developer_manual/basics/front-end/index.html)
* [Translations](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html)
* [Background jobs (Cron)](https://docs.nextcloud.com/server/31/developer_manual/basics/backgroundjobs.html)
* [Caching](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html)
* [Logging](https://docs.nextcloud.com/server/31/developer_manual/basics/logging.html)
* [Settings](https://docs.nextcloud.com/server/31/developer_manual/basics/setting.html)
* [Storage and database](https://docs.nextcloud.com/server/31/developer_manual/basics/storage/index.html)
* [Public share template](https://docs.nextcloud.com/server/31/developer_manual/basics/public_share_template.html)
* [Testing](https://docs.nextcloud.com/server/31/developer_manual/basics/testing.html)
* [App development](https://docs.nextcloud.com/server/31/developer_manual/app_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/app_development/intro.html)
* [Tutorial](https://docs.nextcloud.com/server/31/developer_manual/app_development/tutorial.html)
* [Bootstrapping](https://docs.nextcloud.com/server/31/developer_manual/app_development/bootstrap.html)
* [App metadata](https://docs.nextcloud.com/server/31/developer_manual/app_development/info.html)
* [Navigation and pre-app configuration](https://docs.nextcloud.com/server/31/developer_manual/app_development/init.html)
* [Dependency management](https://docs.nextcloud.com/server/31/developer_manual/app_development/dependency_management.html)
* [Translation setup](https://docs.nextcloud.com/server/31/developer_manual/app_development/translation_setup.html)
* [ExApp development](https://docs.nextcloud.com/server/31/developer_manual/exapp_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/exapp_development/Introduction.html)
* [Setting up dev environment](https://docs.nextcloud.com/server/31/developer_manual/exapp_development/DevSetup.html)
* [Development overview](https://docs.nextcloud.com/server/31/developer_manual/exapp_development/development_overview/index.html)
* [Technical details](https://docs.nextcloud.com/server/31/developer_manual/exapp_development/tech_details/index.html)
* [Frequently Asked Questions](https://docs.nextcloud.com/server/31/developer_manual/exapp_development/faq/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* [Front-end code](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html)
* [Back-end code](https://docs.nextcloud.com/server/31/developer_manual/server/code-back-end.html)
* [Static analysis](https://docs.nextcloud.com/server/31/developer_manual/server/static-analysis.html)
* [Unit-Testing](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html)
* [External API](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html)
* [Nextcloud architecture](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/index.html)
* [How to test …](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/index.html)
* [API reference](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/api.html)
* [Config & Preferences](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/config/index.html)
* [Classloader](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/classloader.html)
* [Continuous Integration](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/continuous_integration.html)
* [Dashboard](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/dashboard.html)
* [Deadlocks](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/deadlock.html)
* [Debugging](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/debugging.html)
* [Email](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/email.html)
* [Files Metadata](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/files-metadata.html)
* [Groupware integration](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/groupware/index.html)
* [HTTP Client](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/http_client.html)
* [JavaScript APIs](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/javascript-apis.html)
* [Machine Translation](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/translation.html)
* [Nextcloud Flow](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/flow.html)
* [NPM](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/npm.html)
* [Notifications](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/notifications.html)
* [Out-of-office periods](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/out_of_office.html)
* [Performance considerations](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/performance.html)
* [Phone number util](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/phonenumberutil.html)
* [PSR](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/psr.html)
* [Profile](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/profile.html)
* [Profiler](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/profiler.html)
* [Projects](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/projects.html)
* [Public Pages](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/publicpage.html)
* [Reference providers](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/reference.html)
* [Repair steps](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/repair.html)
* [REST APIs](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/rest_apis.html)
* [Search](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/search.html)
* [Security](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/security.html)
* [Settings](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/settings.html)
* [Setup checks](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/setup_checks.html)
* [Speech-To-Text](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/speech-to-text.html)
* [Talk Integration](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/talk.html)
* [Task Processing](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/task_processing.html)
* [Text Processing](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/text_processing.html)
* [Text-To-Image](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/text2image.html)
* [Two-factor providers](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/two-factor-provider.html)
* [User Status](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/status.html)
* [User migration](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/user_migration.html)
* [User management](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/users.html)
* [Web Host Metadata](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/web_host_metadata.html)
* [Working with time](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/time.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/index.html)
* [Maintainers](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/maintainer.html)
* [Release process](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html)
* [Publishing App on the App Store](https://nextcloudappstore.readthedocs.io/en/latest/developer.html)
* [Monetizing your app](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/monetizing.html)
* [The Nextcloud app store rules](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/publishing.html)
* [Code signing](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/code_signing.html)
* [Release Automation](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_automation.html)
* [App upgrade guide](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html)
* [Interface & interaction design](https://docs.nextcloud.com/server/31/developer_manual/design/index.html)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/31/developer_manual/design/foundations.html)
* [Layout](https://docs.nextcloud.com/server/31/developer_manual/design/layout.html)
* [Layout components](https://docs.nextcloud.com/server/31/developer_manual/design/layoutcomponents.html)
* [Atomic components](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/index.html)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html)
* [New button](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#new-button)
* [App navigation menu](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#app-navigation-menu)
* [Settings](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#settings)
* [Main content](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/content.html)
* [Content list](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/list.html)
* [Popover menu](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/popovermenu.html)
* [HTML elements](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/html.html)
* [CSS](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/css.html)
* [Icons](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/icons.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/31/developer_manual/client_apis/index.html)
* [General](https://docs.nextcloud.com/server/31/developer_manual/client_apis/general.html)
* [Activity](https://docs.nextcloud.com/server/31/developer_manual/client_apis/activity-api.html)
* [Android](https://docs.nextcloud.com/server/31/developer_manual/client_apis/android_library/index.html)
* [Files](https://docs.nextcloud.com/server/31/developer_manual/client_apis/files.html)
* [Login Flow](https://docs.nextcloud.com/server/31/developer_manual/client_apis/LoginFlow/index.html)
* [OCS API](https://docs.nextcloud.com/server/31/developer_manual/client_apis/OCS/index.html)
* [Remote wipe](https://docs.nextcloud.com/server/31/developer_manual/client_apis/RemoteWipe/index.html)
* [Webdav](https://docs.nextcloud.com/server/31/developer_manual/client_apis/WebDAV/index.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/#)
* Nextcloud developer documentation
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/index.rst)
* * *
Nextcloud developer documentation[](https://docs.nextcloud.com/server/stable/developer_manual/#nextcloud-developer-documentation "Link to this heading")
==========================================================================================================================================================
Table of contents[](https://docs.nextcloud.com/server/stable/developer_manual/#table-of-contents "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------
* [Prologue](https://docs.nextcloud.com/server/stable/developer_manual/prologue/index.html)
* [Code of conduct](https://docs.nextcloud.com/server/stable/developer_manual/prologue/code-of-conduct.html)
* [Help and communication](https://docs.nextcloud.com/server/stable/developer_manual/prologue/help_communication.html)
* [Bugtracker](https://docs.nextcloud.com/server/stable/developer_manual/prologue/bugtracker/index.html)
* [Security guidelines](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html)
* [Compatibility with the app ecosystem](https://docs.nextcloud.com/server/stable/developer_manual/prologue/compatibility_app_ecosystem.html)
* [Getting started](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/index.html)
* [Development process](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/development_process.html)
* [Development environment](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/devenv.html)
* [Coding style & general guidelines](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/coding_standards/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/stable/developer_manual/basics/index.html)
* [Request lifecycle](https://docs.nextcloud.com/server/stable/developer_manual/basics/request_lifecycle.html)
* [Routing](https://docs.nextcloud.com/server/stable/developer_manual/basics/routing.html)
* [Dependency injection](https://docs.nextcloud.com/server/stable/developer_manual/basics/dependency_injection.html)
* [Controllers](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html)
* [Middlewares](https://docs.nextcloud.com/server/stable/developer_manual/basics/middlewares.html)
* [Events](https://docs.nextcloud.com/server/stable/developer_manual/basics/events.html)
* [Front-end](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/index.html)
* [Translations](https://docs.nextcloud.com/server/stable/developer_manual/basics/translations.html)
* [Background jobs (Cron)](https://docs.nextcloud.com/server/stable/developer_manual/basics/backgroundjobs.html)
* [Caching](https://docs.nextcloud.com/server/stable/developer_manual/basics/caching.html)
* [Logging](https://docs.nextcloud.com/server/stable/developer_manual/basics/logging.html)
* [Settings](https://docs.nextcloud.com/server/stable/developer_manual/basics/setting.html)
* [Storage and database](https://docs.nextcloud.com/server/stable/developer_manual/basics/storage/index.html)
* [Public share template](https://docs.nextcloud.com/server/stable/developer_manual/basics/public_share_template.html)
* [Testing](https://docs.nextcloud.com/server/stable/developer_manual/basics/testing.html)
* [App development](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html)
* [Tutorial](https://docs.nextcloud.com/server/stable/developer_manual/app_development/tutorial.html)
* [Bootstrapping](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html)
* [App metadata](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html)
* [Navigation and pre-app configuration](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html)
* [Dependency management](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html)
* [Extending the DAV server](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dav_extension.html)
* [Translation setup](https://docs.nextcloud.com/server/stable/developer_manual/app_development/translation_setup.html)
* [ExApp development](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/Introduction.html)
* [Setting up dev environment](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html)
* [Development overview](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/development_overview/index.html)
* [Technical details](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/index.html)
* [Frequently Asked Questions](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/index.html)
* [Server development](https://docs.nextcloud.com/server/stable/developer_manual/server/index.html)
* [Front-end code](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html)
* [Back-end code](https://docs.nextcloud.com/server/stable/developer_manual/server/code-back-end.html)
* [Static analysis](https://docs.nextcloud.com/server/stable/developer_manual/server/static-analysis.html)
* [Unit-Testing](https://docs.nextcloud.com/server/stable/developer_manual/server/unit-testing.html)
* [External API](https://docs.nextcloud.com/server/stable/developer_manual/server/externalapi.html)
* [Nextcloud architecture](https://docs.nextcloud.com/server/stable/developer_manual/server/architecture/index.html)
* [How to test …](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/index.html)
* [API reference](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/api.html)
* [Config & Preferences](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/config/index.html)
* [Classloader](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/classloader.html)
* [Context Chat](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/context_chat.html)
* [Continuous Integration](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/continuous_integration.html)
* [Dashboard](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/dashboard.html)
* [Deadlocks](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/deadlock.html)
* [Debugging](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/debugging.html)
* [Email](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/email.html)
* [Files Metadata](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/files-metadata.html)
* [Groupware integration](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/groupware/index.html)
* [HTTP Client](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/http_client.html)
* [JavaScript APIs](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/javascript-apis.html)
* [Machine Translation](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/translation.html)
* [Nextcloud Flow](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/flow.html)
* [NPM](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/npm.html)
* [Notifications](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/notifications.html)
* [OpenID Connect (Oidc)](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/oidc.html)
* [Out-of-office periods](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/out_of_office.html)
* [Performance considerations](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/performance.html)
* [Phone number util](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/phonenumberutil.html)
* [PSR](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/psr.html)
* [Profile](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/profile.html)
* [Profiler](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/profiler.html)
* [Projects](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/projects.html)
* [Public Pages](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/publicpage.html)
* [Reference providers](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/reference.html)
* [Repair steps](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/repair.html)
* [REST APIs](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/rest_apis.html)
* [Search](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/search.html)
* [Security](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/security.html)
* [Settings](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/settings.html)
* [Setup checks](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/setup_checks.html)
* [Speech-To-Text](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/speech-to-text.html)
* [Talk Integration](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/talk.html)
* [Task Processing](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/task_processing.html)
* [Text Processing](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/text_processing.html)
* [Text-To-Image](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/text2image.html)
* [Two-factor providers](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/two-factor-provider.html)
* [User Status](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/status.html)
* [User migration](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/user_migration.html)
* [User management](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/users.html)
* [Web Host Metadata](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/web_host_metadata.html)
* [WebDAV collection preload events](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/webdav_collection_preload.html)
* [Working with time](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/time.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/index.html)
* [Maintainers](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/maintainer.html)
* [Release process](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html)
* [Publishing App on the App Store](https://nextcloudappstore.readthedocs.io/en/latest/developer.html)
* [Monetizing your app](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/monetizing.html)
* [The Nextcloud app store rules](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/publishing.html)
* [Code signing](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/code_signing.html)
* [Release Automation](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_automation.html)
* [App upgrade guide](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html)
* [Interface & interaction design](https://docs.nextcloud.com/server/stable/developer_manual/design/index.html)
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/stable/developer_manual/design/foundations.html)
* [Layout](https://docs.nextcloud.com/server/stable/developer_manual/design/layout.html)
* [Layout components](https://docs.nextcloud.com/server/stable/developer_manual/design/layoutcomponents.html)
* [Atomic components](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/index.html)
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/navigation.html)
* [New button](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/navigation.html#new-button)
* [App navigation menu](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/navigation.html#app-navigation-menu)
* [Settings](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/navigation.html#settings)
* [Main content](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/content.html)
* [Content list](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/list.html)
* [Popover menu](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/popovermenu.html)
* [HTML elements](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/html.html)
* [CSS](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/css.html)
* [Icons](https://docs.nextcloud.com/server/stable/developer_manual/html_css_design/icons.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/index.html)
* [General](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/general.html)
* [Activity](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/activity-api.html)
* [Android](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/android_library/index.html)
* [Files](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/files.html)
* [Login Flow](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/LoginFlow/index.html)
* [OCS API](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/OCS/index.html)
* [Remote wipe](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/RemoteWipe/index.html)
* [Webdav](https://docs.nextcloud.com/server/stable/developer_manual/client_apis/WebDAV/index.html)
* [Desktop Clients](https://docs.nextcloud.com/server/stable/developer_manual/desktop/index.html)
* [Building the Client](https://docs.nextcloud.com/server/stable/developer_manual/desktop/building.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Nextcloud developer documentation — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/#)
* Nextcloud developer documentation
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/index.rst)
* * *
Nextcloud developer documentation[](https://docs.nextcloud.com/server/32/developer_manual/#nextcloud-developer-documentation "Link to this heading")
======================================================================================================================================================
Table of contents[](https://docs.nextcloud.com/server/32/developer_manual/#table-of-contents "Link to this heading")
----------------------------------------------------------------------------------------------------------------------
* [Prologue](https://docs.nextcloud.com/server/32/developer_manual/prologue/index.html)
* [Code of conduct](https://docs.nextcloud.com/server/32/developer_manual/prologue/code-of-conduct.html)
* [Help and communication](https://docs.nextcloud.com/server/32/developer_manual/prologue/help_communication.html)
* [Bugtracker](https://docs.nextcloud.com/server/32/developer_manual/prologue/bugtracker/index.html)
* [Security guidelines](https://docs.nextcloud.com/server/32/developer_manual/prologue/security.html)
* [Compatibility with the app ecosystem](https://docs.nextcloud.com/server/32/developer_manual/prologue/compatibility_app_ecosystem.html)
* [Getting started](https://docs.nextcloud.com/server/32/developer_manual/getting_started/index.html)
* [Development process](https://docs.nextcloud.com/server/32/developer_manual/getting_started/development_process.html)
* [Development environment](https://docs.nextcloud.com/server/32/developer_manual/getting_started/devenv.html)
* [Coding style & general guidelines](https://docs.nextcloud.com/server/32/developer_manual/getting_started/coding_standards/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/32/developer_manual/basics/index.html)
* [Request lifecycle](https://docs.nextcloud.com/server/32/developer_manual/basics/request_lifecycle.html)
* [Routing](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html)
* [Dependency injection](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html)
* [Controllers](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html)
* [Middlewares](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html)
* [Events](https://docs.nextcloud.com/server/32/developer_manual/basics/events.html)
* [Front-end](https://docs.nextcloud.com/server/32/developer_manual/basics/front-end/index.html)
* [Translations](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html)
* [Background jobs (Cron)](https://docs.nextcloud.com/server/32/developer_manual/basics/backgroundjobs.html)
* [Caching](https://docs.nextcloud.com/server/32/developer_manual/basics/caching.html)
* [Logging](https://docs.nextcloud.com/server/32/developer_manual/basics/logging.html)
* [Settings](https://docs.nextcloud.com/server/32/developer_manual/basics/setting.html)
* [Storage and database](https://docs.nextcloud.com/server/32/developer_manual/basics/storage/index.html)
* [Public share template](https://docs.nextcloud.com/server/32/developer_manual/basics/public_share_template.html)
* [Testing](https://docs.nextcloud.com/server/32/developer_manual/basics/testing.html)
* [App development](https://docs.nextcloud.com/server/32/developer_manual/app_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html)
* [Tutorial](https://docs.nextcloud.com/server/32/developer_manual/app_development/tutorial.html)
* [Bootstrapping](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html)
* [App metadata](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html)
* [Navigation and pre-app configuration](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html)
* [Dependency management](https://docs.nextcloud.com/server/32/developer_manual/app_development/dependency_management.html)
* [Extending the DAV server](https://docs.nextcloud.com/server/32/developer_manual/app_development/dav_extension.html)
* [Translation setup](https://docs.nextcloud.com/server/32/developer_manual/app_development/translation_setup.html)
* [ExApp development](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/index.html)
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/Introduction.html)
* [Setting up dev environment](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html)
* [Development overview](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/development_overview/index.html)
* [Technical details](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/index.html)
* [Frequently Asked Questions](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/index.html)
* [Server development](https://docs.nextcloud.com/server/32/developer_manual/server/index.html)
* [Front-end code](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html)
* [Back-end code](https://docs.nextcloud.com/server/32/developer_manual/server/code-back-end.html)
* [Static analysis](https://docs.nextcloud.com/server/32/developer_manual/server/static-analysis.html)
* [Unit-Testing](https://docs.nextcloud.com/server/32/developer_manual/server/unit-testing.html)
* [External API](https://docs.nextcloud.com/server/32/developer_manual/server/externalapi.html)
* [Nextcloud architecture](https://docs.nextcloud.com/server/32/developer_manual/server/architecture/index.html)
* [How to test …](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/index.html)
* [API reference](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/api.html)
* [Config & Preferences](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/config/index.html)
* [Classloader](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/classloader.html)
* [Context Chat](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/context_chat.html)
* [Continuous Integration](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/continuous_integration.html)
* [Dashboard](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/dashboard.html)
* [Deadlocks](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/deadlock.html)
* [Debugging](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/debugging.html)
* [Email](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/email.html)
* [Files Metadata](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/files-metadata.html)
* [Groupware integration](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/groupware/index.html)
* [HTTP Client](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/http_client.html)
* [JavaScript APIs](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/javascript-apis.html)
* [Machine Translation](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/translation.html)
* [Nextcloud Flow](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/flow.html)
* [NPM](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/npm.html)
* [Notifications](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/notifications.html)
* [OpenID Connect (Oidc)](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/oidc.html)
* [Out-of-office periods](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/out_of_office.html)
* [Performance considerations](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/performance.html)
* [Phone number util](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/phonenumberutil.html)
* [PSR](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/psr.html)
* [Profile](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/profile.html)
* [Profiler](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/profiler.html)
* [Projects](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/projects.html)
* [Public Pages](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/publicpage.html)
* [Reference providers](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/reference.html)
* [Repair steps](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/repair.html)
* [REST APIs](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/rest_apis.html)
* [Search](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/search.html)
* [Security](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/security.html)
* [Settings](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/settings.html)
* [Setup checks](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/setup_checks.html)
* [Speech-To-Text](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/speech-to-text.html)
* [Talk Integration](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/talk.html)
* [Task Processing](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/task_processing.html)
* [Text Processing](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/text_processing.html)
* [Text-To-Image](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/text2image.html)
* [Two-factor providers](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/two-factor-provider.html)
* [User Status](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/status.html)
* [User migration](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/user_migration.html)
* [User management](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/users.html)
* [Web Host Metadata](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/web_host_metadata.html)
* [WebDAV collection preload events](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/webdav_collection_preload.html)
* [Working with time](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/time.html)
* [App publishing and maintenance](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/index.html)
* [Maintainers](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/maintainer.html)
* [Release process](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html)
* [Publishing App on the App Store](https://nextcloudappstore.readthedocs.io/en/latest/developer.html)
* [Monetizing your app](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/monetizing.html)
* [The Nextcloud app store rules](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/publishing.html)
* [Code signing](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/code_signing.html)
* [Release Automation](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_automation.html)
* [App upgrade guide](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html)
* [Interface & interaction design](https://docs.nextcloud.com/server/32/developer_manual/design/index.html)
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/32/developer_manual/design/foundations.html)
* [Layout](https://docs.nextcloud.com/server/32/developer_manual/design/layout.html)
* [Layout components](https://docs.nextcloud.com/server/32/developer_manual/design/layoutcomponents.html)
* [Atomic components](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html)
* [HTML/CSS guidelines](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/index.html)
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/navigation.html)
* [New button](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/navigation.html#new-button)
* [App navigation menu](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/navigation.html#app-navigation-menu)
* [Settings](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/navigation.html#settings)
* [Main content](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/content.html)
* [Content list](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/list.html)
* [Popover menu](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/popovermenu.html)
* [HTML elements](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/html.html)
* [CSS](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/css.html)
* [Icons](https://docs.nextcloud.com/server/32/developer_manual/html_css_design/icons.html)
* [Clients and Client APIs](https://docs.nextcloud.com/server/32/developer_manual/client_apis/index.html)
* [General](https://docs.nextcloud.com/server/32/developer_manual/client_apis/general.html)
* [Activity](https://docs.nextcloud.com/server/32/developer_manual/client_apis/activity-api.html)
* [Android](https://docs.nextcloud.com/server/32/developer_manual/client_apis/android_library/index.html)
* [Files](https://docs.nextcloud.com/server/32/developer_manual/client_apis/files.html)
* [Login Flow](https://docs.nextcloud.com/server/32/developer_manual/client_apis/LoginFlow/index.html)
* [OCS API](https://docs.nextcloud.com/server/32/developer_manual/client_apis/OCS/index.html)
* [Remote wipe](https://docs.nextcloud.com/server/32/developer_manual/client_apis/RemoteWipe/index.html)
* [Webdav](https://docs.nextcloud.com/server/32/developer_manual/client_apis/WebDAV/index.html)
* [Desktop Clients](https://docs.nextcloud.com/server/32/developer_manual/desktop/index.html)
* [Building the Client](https://docs.nextcloud.com/server/32/developer_manual/desktop/building.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Desktop Clients — Nextcloud latest Administration Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/admin_manual/contents.html)
* Desktop Clients
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/admin_manual/desktop/index.rst)
* * *
Desktop Clients[](https://docs.nextcloud.com/server/latest/admin_manual/desktop/index.html#desktop-clients "Link to this heading")
====================================================================================================================================
Available for Windows, macOS, and various Linux distributions, the Nextcloud Desktop Sync client enables you to:
* Specify one or more directories on your computer that you want to synchronize to the Nextcloud server.
* Always have the latest files synchronized, wherever they are located.
Your files are always automatically synchronized between your Nextcloud server, computer and mobile device.
* [Options](https://docs.nextcloud.com/server/latest/admin_manual/desktop/options.html)
* [Mass Deployment And Account Creation](https://docs.nextcloud.com/server/latest/admin_manual/desktop/massdeployment.html)
* [Configuration File](https://docs.nextcloud.com/server/latest/admin_manual/desktop/configfile.html)
* [Environment Variables](https://docs.nextcloud.com/server/latest/admin_manual/desktop/envvars.html)
* [Command Line Client](https://docs.nextcloud.com/server/latest/admin_manual/desktop/commandline.html)
* [Command-line Account Setup](https://docs.nextcloud.com/server/latest/admin_manual/desktop/accountcommand.html)
* [Troubleshooting](https://docs.nextcloud.com/server/latest/admin_manual/desktop/troubleshooting.html)
You can find additional information here:
* [User manual](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/index.html)
* [Developer manual](https://docs.nextcloud.com/server/latest/developer_manual/desktop/index.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/admin_manual)
[stable](https://docs.nextcloud.com/server/stable/admin_manual)
[32](https://docs.nextcloud.com/server/32/admin_manual)
[31](https://docs.nextcloud.com/server/31/admin_manual)
---
# Installation and server configuration — Nextcloud latest Administration Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/admin_manual/contents.html)
* Installation and server configuration
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/admin_manual/installation/index.rst)
* * *
Installation and server configuration[](https://docs.nextcloud.com/server/latest/admin_manual/installation/index.html#installation-and-server-configuration "Link to this heading")
=====================================================================================================================================================================================
* [System requirements](https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html)
* [Server](https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#server)
* [Desktop client](https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#desktop-client)
* [Mobile apps](https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#mobile-apps)
* [Web browser](https://docs.nextcloud.com/server/latest/admin_manual/installation/system_requirements.html#web-browser)
* [Deployment recommendations](https://docs.nextcloud.com/server/latest/admin_manual/installation/deployment_recommendations.html)
* [Preparing PHP](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html)
* [PHP Installation](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#php-installation)
* [Required PHP Modules](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#required-php-modules)
* [Required PHP Database Connectors](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#required-php-database-connectors)
* [Recommended General PHP Modules](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#recommended-general-php-modules)
* [Recommended PHP Caching Modules](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#recommended-php-caching-modules)
* [Recommended PHP CLI Modules](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#recommended-php-cli-modules)
* [PHP Modules for Media Management](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#php-modules-for-media-management)
* [PHP Modules for Specific Applications](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#php-modules-for-specific-applications)
* [PHP ini Settings](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#php-ini-settings)
* [Notes on PHP ini Configuration](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#notes-on-php-ini-configuration)
* [PHP Module Quick Reference Table](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#php-module-quick-reference-table)
* [Further Resources](https://docs.nextcloud.com/server/latest/admin_manual/installation/php_configuration.html#further-resources)
* [Installation on Linux](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html)
* [Prerequisites for manual installation](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation)
* [Apache Web server configuration](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#apache-web-server-configuration)
* [Pretty URLs](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#pretty-urls)
* [Enabling SSL](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#enabling-ssl)
* [Installation wizard](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#installation-wizard)
* [Setting up background jobs](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#setting-up-background-jobs)
* [SELinux configuration tips](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#selinux-configuration-tips)
* [PHP-FPM configuration](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#php-fpm-configuration)
* [Other Web servers](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#other-web-servers)
* [Installing on Windows (virtual machine)](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#installing-on-windows-virtual-machine)
* [Installing via Snap packages](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#installing-via-snap-packages)
* [Installation via web installer on a VPS or web space](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#installation-via-web-installer-on-a-vps-or-web-space)
* [Installation on TrueNAS](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#installation-on-truenas)
* [Installation via install script](https://docs.nextcloud.com/server/latest/admin_manual/installation/source_installation.html#installation-via-install-script)
* [Installation wizard](https://docs.nextcloud.com/server/latest/admin_manual/installation/installation_wizard.html)
* [Quick start](https://docs.nextcloud.com/server/latest/admin_manual/installation/installation_wizard.html#quick-start)
* [Data directory location](https://docs.nextcloud.com/server/latest/admin_manual/installation/installation_wizard.html#data-directory-location)
* [Database choice](https://docs.nextcloud.com/server/latest/admin_manual/installation/installation_wizard.html#database-choice)
* [Trusted domains](https://docs.nextcloud.com/server/latest/admin_manual/installation/installation_wizard.html#trusted-domains)
* [Installing from command line](https://docs.nextcloud.com/server/latest/admin_manual/installation/command_line_installation.html)
* [SELinux configuration](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html)
* [Enable updates via the web interface](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#enable-updates-via-the-web-interface)
* [Disallow write access to the whole web directory](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#disallow-write-access-to-the-whole-web-directory)
* [Allow access to a remote database](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-a-remote-database)
* [Allow access to LDAP server](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-ldap-server)
* [Allow access to remote network](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-remote-network)
* [Allow access to network memcache](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-network-memcache)
* [Allow access to SMTP/sendmail](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-smtp-sendmail)
* [Allow access to CIFS/SMB](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-cifs-smb)
* [Allow access to FuseFS](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-fusefs)
* [Allow access to GPG for Rainloop](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#allow-access-to-gpg-for-rainloop)
* [Troubleshooting](https://docs.nextcloud.com/server/latest/admin_manual/installation/selinux_configuration.html#troubleshooting)
* [NGINX configuration](https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html)
* [Nextcloud in the webroot of NGINX](https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html#nextcloud-in-the-webroot-of-nginx)
* [Nextcloud in a subdir of the NGINX webroot](https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html#nextcloud-in-a-subdir-of-the-nginx-webroot)
* [Tips and tricks](https://docs.nextcloud.com/server/latest/admin_manual/installation/nginx.html#tips-and-tricks)
* [Hardening and security guidance](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html)
* [Passwords](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#passwords)
* [Operating system](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#operating-system)
* [Deployment](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#deployment)
* [Use HTTPS](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#use-https)
* [Restrict admin actions to a specific range of IP addresses](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#restrict-admin-actions-to-a-specific-range-of-ip-addresses)
* [Use a dedicated domain for Nextcloud](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#use-a-dedicated-domain-for-nextcloud)
* [Ensure that your Nextcloud instance is installed in a DMZ](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#ensure-that-your-nextcloud-instance-is-installed-in-a-dmz)
* [Serve security related headers by the Web server](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#serve-security-related-headers-by-the-web-server)
* [Connections to remote servers](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#connections-to-remote-servers)
* [Setup fail2ban](https://docs.nextcloud.com/server/latest/admin_manual/installation/harden_server.html#setup-fail2ban)
* [Server tuning](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html)
* [Using cron to perform background jobs](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#using-cron-to-perform-background-jobs)
* [Reducing system load](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#reducing-system-load)
* [Log Levels](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#log-levels)
* [Debug Mode](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#debug-mode)
* [Caching](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#id1)
* [Compression](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#compression)
* [Replacing SQLite](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#replacing-sqlite)
* [Tuning your database](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#tuning-your-database)
* [Using Redis-based transactional file locking](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#using-redis-based-transactional-file-locking)
* [TLS / encryption app](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#tls-encryption-app)
* [Enable HTTP/2 for faster loading](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-http-2-for-faster-loading)
* [Tune PHP-FPM](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#tune-php-fpm)
* [Enable PHP OPcache](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#enable-php-opcache)
* [Previews](https://docs.nextcloud.com/server/latest/admin_manual/installation/server_tuning.html#previews)
* [Example installation on Ubuntu 22.04 LTS](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_ubuntu.html)
* [Next steps](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_ubuntu.html#next-steps)
* [Example installation on CentOS 8](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html)
* [Apache](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html#apache)
* [PHP](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html#php)
* [Database](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html#database)
* [Redis](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html#redis)
* [Installing Nextcloud](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html#installing-nextcloud)
* [SELinux](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_centos.html#selinux)
* [Example installation on OpenBSD](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html)
* [HTTPD(8)](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#httpd-8)
* [PHP](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#php)
* [Database](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#database)
* [Redis](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#redis)
* [Cron job](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#cron-job)
* [Chroot](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#chroot)
* [Nextcloud final steps](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#nextcloud-final-steps)
* [NOTE](https://docs.nextcloud.com/server/latest/admin_manual/installation/example_openbsd.html#note)
* [Uninstallation](https://docs.nextcloud.com/server/latest/admin_manual/installation/uninstallation.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/admin_manual)
[stable](https://docs.nextcloud.com/server/stable/admin_manual)
[32](https://docs.nextcloud.com/server/32/admin_manual)
[31](https://docs.nextcloud.com/server/31/admin_manual)
---
# Administration privileges (Delegation) — Nextcloud latest Administration Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/admin_manual/contents.html)
* [Nextcloud configuration](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/index.html)
* Administration privileges (Delegation)
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/admin_manual/configuration_server/admin_delegation_configuration.rst)
* * *
Administration privileges (Delegation)[](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/admin_delegation_configuration.html#administration-privileges-delegation "Link to this heading")
======================================================================================================================================================================================================================
Introduction[](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/admin_delegation_configuration.html#introduction "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nextcloud has built-in functionality which permits administrators to delegate authority to others without granting them full administration privileges (and without making them a member of the `admin` group).
This administration privilege delegation functionality is supported by many shipped and ecosystem apps that have their own settings areas under _Administration settings_.
Note
If you’re an app developer and would like administrators to be able to utilize this functionality for your app, you need to enable support for delegation of your settings (see the Developer Manual for specifics).
Tip
Delegation of user management is possible, but you can also use [Group Administrators](https://docs.nextcloud.com/server/latest/admin_manual/configuration_user/user_configuration.html)
.
Warning
Delegation of user management allow the delegated users to add themselves to groups receiving delegation of other settings. This can be used to escalate privileges.
Usage[](https://docs.nextcloud.com/server/latest/admin_manual/configuration_server/admin_delegation_configuration.html#usage "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
By default only members of the `admin` group can access _Administration settings_. You can create additional user groups (or use existing ones) and then grant these groups access to specific settings.
While logged in to an account that is a member of the `admin` group, go to _Administration settings_ -> _Administration privilege_. You will be presented with the list of settings pages and sections, including for any installed apps, that support delegation.

By clicking on the combo box, you will be able to choose which groups are able to access the selected settings. You can revoke access at any time by removing the group from the selection (or, if you wish only to revoke access for an individual account, by removing that account from the configured group).
Tip
Not every settings page or section supports delegation. This is either because delegating access to that particular settings page would enable privilege escalation (i.e. bypassing of the limited administration authority) or delegation has not yet been implemented for that specific settings page or app.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/admin_manual)
[stable](https://docs.nextcloud.com/server/stable/admin_manual)
[32](https://docs.nextcloud.com/server/32/admin_manual)
[31](https://docs.nextcloud.com/server/31/admin_manual)
---
# Desktop Clients — Nextcloud latest User Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/user_manual/en/contents.html)
* Desktop Clients
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/user_manual/desktop/index.rst)
* * *
Desktop Clients[](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/index.html#desktop-clients "Link to this heading")
======================================================================================================================================
Available for Windows, macOS, and various Linux distributions, the Nextcloud Desktop Sync client enables you to:
* Specify one or more directories on your computer that you want to synchronize to the Nextcloud server.
* Always have the latest files synchronized, wherever they are located.
Your files are always automatically synchronized between your Nextcloud server, computer and mobile device.
* [Installation](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/installation.html)
* [Using the Synchronization Client](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/usage.html)
* [macOS Virtual Files Client](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/macosvfs.html)
* [The Automatic Updater](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/autoupdate.html)
* [Update channels](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/updatechannel.html)
* [Conflicts](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/conflicts.html)
* [FAQ](https://docs.nextcloud.com/server/latest/user_manual/en/desktop/faq.html)
You can find additional information here:
* [Admin manual](https://docs.nextcloud.com/server/latest/admin_manual/desktop/index.html)
* [Developer manual](https://docs.nextcloud.com/server/latest/developer_manual/desktop/index.html)
🌐 English ☁️ latest
🌐 Languages
[Arabic](https://docs.nextcloud.com/server/latest/user_manual/ar/)
[Breton](https://docs.nextcloud.com/server/latest/user_manual/br/)
[Catalan](https://docs.nextcloud.com/server/latest/user_manual/ca/)
[Chinese](https://docs.nextcloud.com/server/latest/user_manual/zh_CN/)
[Chinese (HK)](https://docs.nextcloud.com/server/latest/user_manual/zh_HK/)
[Chinese (TW)](https://docs.nextcloud.com/server/latest/user_manual/zh_TW/)
[Czech](https://docs.nextcloud.com/server/latest/user_manual/cs/)
[Danish](https://docs.nextcloud.com/server/latest/user_manual/da/)
[Dutch](https://docs.nextcloud.com/server/latest/user_manual/nl/)
[English](https://docs.nextcloud.com/server/latest/user_manual/en/)
[Finnish](https://docs.nextcloud.com/server/latest/user_manual/fi_FI/)
[French](https://docs.nextcloud.com/server/latest/user_manual/fr/)
[Galician](https://docs.nextcloud.com/server/latest/user_manual/gl/)
[German](https://docs.nextcloud.com/server/latest/user_manual/de/)
[Greek](https://docs.nextcloud.com/server/latest/user_manual/el/)
[Hungarian](https://docs.nextcloud.com/server/latest/user_manual/hu_HU/)
[Indonesian](https://docs.nextcloud.com/server/latest/user_manual/id/)
[Irish](https://docs.nextcloud.com/server/latest/user_manual/ga/)
[Italian](https://docs.nextcloud.com/server/latest/user_manual/it/)
[Japanese](https://docs.nextcloud.com/server/latest/user_manual/ja_JP/)
[Korean](https://docs.nextcloud.com/server/latest/user_manual/ko/)
[Mongolian](https://docs.nextcloud.com/server/latest/user_manual/mn/)
[Norwegian (NB)](https://docs.nextcloud.com/server/latest/user_manual/nb_NO/)
[Norwegian (NN)](https://docs.nextcloud.com/server/latest/user_manual/nn/)
[Polish](https://docs.nextcloud.com/server/latest/user_manual/pl/)
[Portuguese](https://docs.nextcloud.com/server/latest/user_manual/pt_PT/)
[Portuguese (BR)](https://docs.nextcloud.com/server/latest/user_manual/pt_BR/)
[Romanian](https://docs.nextcloud.com/server/latest/user_manual/ro/)
[Russian](https://docs.nextcloud.com/server/latest/user_manual/ru/)
[Sinhala](https://docs.nextcloud.com/server/latest/user_manual/si/)
[Slovakian](https://docs.nextcloud.com/server/latest/user_manual/sk_SK/)
[Slovenian](https://docs.nextcloud.com/server/latest/user_manual/sr/)
[Spanish](https://docs.nextcloud.com/server/latest/user_manual/es/)
[Swedish](https://docs.nextcloud.com/server/latest/user_manual/sv/)
[Tamil](https://docs.nextcloud.com/server/latest/user_manual/ta/)
[Turkish](https://docs.nextcloud.com/server/latest/user_manual/tr/)
[Ukrainian](https://docs.nextcloud.com/server/latest/user_manual/uk_UA/)
[Uzbek](https://docs.nextcloud.com/server/latest/user_manual/uz/)
[Vietnamese](https://docs.nextcloud.com/server/latest/user_manual/vi/)
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/user_manual)
[stable](https://docs.nextcloud.com/server/stable/user_manual)
[32](https://docs.nextcloud.com/server/32/user_manual)
[31](https://docs.nextcloud.com/server/31/user_manual)
Downloads
On Read the Docs
[Project Home](///projects//?fromdocs=)
[Builds](///builds//?fromdocs=)
---
# Prologue — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* Prologue
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/index.rst)
* * *
Prologue[](https://docs.nextcloud.com/server/31/developer_manual/prologue/index.html#prologue "Link to this heading")
=======================================================================================================================
* [Code of conduct](https://docs.nextcloud.com/server/31/developer_manual/prologue/code-of-conduct.html)
* [Help and communication](https://docs.nextcloud.com/server/31/developer_manual/prologue/help_communication.html)
* [Forums](https://docs.nextcloud.com/server/31/developer_manual/prologue/help_communication.html#forums)
* [Maintainers](https://docs.nextcloud.com/server/31/developer_manual/prologue/help_communication.html#maintainers)
* [Bugtracker](https://docs.nextcloud.com/server/31/developer_manual/prologue/bugtracker/index.html)
* [Security guidelines](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html)
* [SQL injection](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#sql-injection)
* [Cross site scripting](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#cross-site-scripting)
* [Clickjacking](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#clickjacking)
* [Code executions / file inclusions](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#code-executions-file-inclusions)
* [Directory traversal](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#directory-traversal)
* [Shell injection](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#shell-injection)
* [Auth bypass / privilege escalations](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#auth-bypass-privilege-escalations)
* [Sensitive data exposure](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#sensitive-data-exposure)
* [Cross site request forgery](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#cross-site-request-forgery)
* [Unvalidated redirects](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#unvalidated-redirects)
* [Getting help](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#getting-help)
* [Compatibility with the app ecosystem](https://docs.nextcloud.com/server/31/developer_manual/prologue/compatibility_app_ecosystem.html)
* [Documentation procedures of changes that affect app developers](https://docs.nextcloud.com/server/31/developer_manual/prologue/compatibility_app_ecosystem.html#documentation-procedures-of-changes-that-affect-app-developers)
* [Other documentation requirements](https://docs.nextcloud.com/server/31/developer_manual/prologue/compatibility_app_ecosystem.html#other-documentation-requirements)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Getting started — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* Getting started
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/getting_started/index.rst)
* * *
Getting started[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/index.html#getting-started "Link to this heading")
============================================================================================================================================
* [Development process](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html)
* [Source Code Version Control](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#source-code-version-control)
* [Target Branches for Contributions](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#target-branches-for-contributions)
* [Development environment](https://docs.nextcloud.com/server/31/developer_manual/getting_started/devenv.html)
* [Set up Web server and database](https://docs.nextcloud.com/server/31/developer_manual/getting_started/devenv.html#set-up-web-server-and-database)
* [Get the source](https://docs.nextcloud.com/server/31/developer_manual/getting_started/devenv.html#get-the-source)
* [Coding style & general guidelines](https://docs.nextcloud.com/server/31/developer_manual/getting_started/coding_standards/index.html)
* [General](https://docs.nextcloud.com/server/31/developer_manual/getting_started/coding_standards/index.html#general)
* [Labels](https://docs.nextcloud.com/server/31/developer_manual/getting_started/coding_standards/index.html#labels)
* [User interface](https://docs.nextcloud.com/server/31/developer_manual/getting_started/coding_standards/index.html#user-interface)
* [Coding standards](https://docs.nextcloud.com/server/31/developer_manual/getting_started/coding_standards/index.html#coding-standards)
* [License headers](https://docs.nextcloud.com/server/31/developer_manual/getting_started/coding_standards/index.html#license-headers)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Prologue — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* Prologue
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/index.rst)
* * *
Prologue[](https://docs.nextcloud.com/server/stable/developer_manual/prologue/index.html#prologue "Link to this heading")
===========================================================================================================================
* [Code of conduct](https://docs.nextcloud.com/server/stable/developer_manual/prologue/code-of-conduct.html)
* [Help and communication](https://docs.nextcloud.com/server/stable/developer_manual/prologue/help_communication.html)
* [Forums](https://docs.nextcloud.com/server/stable/developer_manual/prologue/help_communication.html#forums)
* [Maintainers](https://docs.nextcloud.com/server/stable/developer_manual/prologue/help_communication.html#maintainers)
* [Bugtracker](https://docs.nextcloud.com/server/stable/developer_manual/prologue/bugtracker/index.html)
* [Security guidelines](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html)
* [SQL injection](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#sql-injection)
* [Cross site scripting](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#cross-site-scripting)
* [Clickjacking](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#clickjacking)
* [Code executions / file inclusions](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#code-executions-file-inclusions)
* [Directory traversal](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#directory-traversal)
* [Shell injection](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#shell-injection)
* [Auth bypass / privilege escalations](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#auth-bypass-privilege-escalations)
* [Sensitive data exposure](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#sensitive-data-exposure)
* [Cross site request forgery](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#cross-site-request-forgery)
* [Unvalidated redirects](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#unvalidated-redirects)
* [Getting help](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#getting-help)
* [Compatibility with the app ecosystem](https://docs.nextcloud.com/server/stable/developer_manual/prologue/compatibility_app_ecosystem.html)
* [Documentation procedures of changes that affect app developers](https://docs.nextcloud.com/server/stable/developer_manual/prologue/compatibility_app_ecosystem.html#documentation-procedures-of-changes-that-affect-app-developers)
* [Other documentation requirements](https://docs.nextcloud.com/server/stable/developer_manual/prologue/compatibility_app_ecosystem.html#other-documentation-requirements)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Server development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* Server development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/index.rst)
* * *
Server development[](https://docs.nextcloud.com/server/31/developer_manual/server/index.html#server-development "Link to this heading")
=========================================================================================================================================
Please make sure you have set up a [Development environment](https://docs.nextcloud.com/server/31/developer_manual/getting_started/devenv.html#devenv)
.
* [Front-end code](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html)
* [Building Vue components and scripts](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html#building-vue-components-and-scripts)
* [Building styles](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html#building-styles)
* [Committing changes](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html#committing-changes)
* [Back-end code](https://docs.nextcloud.com/server/31/developer_manual/server/code-back-end.html)
* [Compatibility documentation](https://docs.nextcloud.com/server/31/developer_manual/server/code-back-end.html#compatibility-documentation)
* [Static analysis](https://docs.nextcloud.com/server/31/developer_manual/server/static-analysis.html)
* [PHP static analysis](https://docs.nextcloud.com/server/31/developer_manual/server/static-analysis.html#php-static-analysis)
* [Unit-Testing](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html)
* [PHP unit testing](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html#php-unit-testing)
* [JavaScript unit testing for server](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html#javascript-unit-testing-for-server)
* [External API](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#introduction)
* [Usage](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#usage)
* [Nextcloud architecture](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/index.html)
* [Nextcloud filesystem API](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html)
* [How to test …](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html)
* [Email sending](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#email-sending)
* [Redis](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#redis)
* [Redis Cluster](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#redis-cluster)
* [Primary object store with S3](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#primary-object-store-with-s3)
* [S3 external storage](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#s3-external-storage)
* [SMB external storage](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#smb-external-storage)
* [SAML setup with onelogin](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#saml-setup-with-onelogin)
* [Collabora without SSL](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#collabora-without-ssl)
* [OnlyOffice](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#onlyoffice)
* [WebAuthn without SSL](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#webauthn-without-ssl)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# ExApp development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* ExApp development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/index.rst)
* * *
ExApp development[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/index.html#exapp-development "Link to this heading")
======================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/Introduction.html)
* [Overview](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/Introduction.html#overview)
* [Glossary](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/Introduction.html#glossary)
* [Setting up dev environment](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html)
* [Install AppAPI](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#install-appapi)
* [In Place of a Conclusion](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#in-place-of-a-conclusion)
* [Development overview](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/development_overview/index.html)
* [ExApp development](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html)
* [ExApp overview](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/development_overview/ExAppOverview.html)
* [ExApp lifecycle](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/development_overview/ExAppLifecycle.html)
* [Technical details](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/index.html)
* [App Installation Flow](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/InstallationFlow.html)
* [Deployment](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/Deployment.html)
* [Authentication](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/Authentication.html)
* [Translations](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/Translations.html)
* [AppAPI Nextcloud APIs](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/api/index.html)
* [Frequently Asked Questions](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/index.html)
* [Docker Container Registry](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/DockerContainerRegistry.html)
* [Docker Socket Proxy](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/DockerSocketProxy.html)
* [GPU support](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/GpuSupport.html)
* [Scaling](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/Scaling.html)
* [Corporate Proxy - Permanent Settings for PHP CLI](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/BehindCompanyProxy.html)
* [Troubleshooting](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/faq/Troubleshooting.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# App development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* App development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/index.rst)
* * *
App development[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html#app-development "Link to this heading")
================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html)
* [Create an app](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#create-an-app)
* [Edit an existing app](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#edit-an-existing-app)
* [Enable the app](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#enable-the-app)
* [App architecture](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#app-architecture)
* [Tutorial](https://docs.nextcloud.com/server/stable/developer_manual/app_development/tutorial.html)
* [Bootstrapping](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html)
* [The Application class](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#the-application-class)
* [Bootstrapping process](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#bootstrapping-process)
* [App metadata](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html)
* [Changelog](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html#changelog)
* [Navigation and pre-app configuration](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html)
* [Adding a navigation entry](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html#adding-a-navigation-entry)
* [Initialization events](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html#initialization-events)
* [Dependency management](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html)
* [Composer](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#composer)
* [Extending the DAV server](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dav_extension.html)
* [Registering a DAV plugin](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dav_extension.html#registering-a-dav-plugin)
* [Handling DAV events](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dav_extension.html#handling-dav-events)
* [Performance considerations](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dav_extension.html#performance-considerations)
* [Translation setup](https://docs.nextcloud.com/server/stable/developer_manual/app_development/translation_setup.html)
* [Translation tool](https://docs.nextcloud.com/server/stable/developer_manual/app_development/translation_setup.html#translation-tool)
* [Setup of the transifex sync](https://docs.nextcloud.com/server/stable/developer_manual/app_development/translation_setup.html#setup-of-the-transifex-sync)
* [Manual translation](https://docs.nextcloud.com/server/stable/developer_manual/app_development/translation_setup.html#manual-translation)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Declarative settings — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/developer_manual/index.html)
* [Digging deeper](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/index.html)
* [Settings](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/settings.html)
* Declarative settings
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/digging_deeper/declarative_settings.rst)
* * *
Declarative settings[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#declarative-settings "Link to this heading")
========================================================================================================================================================================
Added in version 29.0.0.
With Nextcloud 29 there is a new way to define app settings in a declarative way. This means that you can just register your settings schema without writing a custom settings handling front-end and back-end code (except when more complex settings logic or design is required).
Registering settings schema[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#registering-settings-schema "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are two ways to register a declarative settings schema:
1. Class-based using `OCP\Settings\IDeclarativeSettingsForm` interface
2. By using an event listener for the `OCP\Settings\Events\DeclarativeSettingsRegisterFormEvent`
Additionally, you can register multiple declarative parameter schemes per application.
Note
Form fields ids (configkeys) must be unique within an app.
Class-based schema registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#class-based-schema-registration "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To register a declarative settings schema using a class, you need to create a class that implements the `OCP\Settings\IDeclarativeSettingsForm` interface:
'my\_declarative\_settings\_form', // unique form id\
'priority' \=> 10, // declarative section priority (ordering)\
'section\_type' \=> DeclarativeSettingsTypes::SECTION\_TYPE\_ADMIN, // admin, personal\
'section\_id' \=> 'my\_section\_id', // existing section id or your custom section id\
'storage\_type' \=> DeclarativeSettingsTypes::STORAGE\_TYPE\_INTERNAL, // external, internal (handled by core to store in appconfig and preferences)\
'title' \=> 'MyApp settings title', // NcSettingsSection name\
'description' \=> 'My app settings section description', // NcSettingsSection description\
'doc\_url' \=> '', // NcSettingsSection doc\_url for documentation or help page, empty string if not needed\
'fields' \=> \[\
\[\
'id' \=> 'my\_field\_key', // configkey\
'title' \=> 'Field title', // name or label\
'description' \=> 'Additional setting hint or description', // hint\
'type' \=> DeclarativeSettingsTypes::MULTI\_SELECT,\
'options' \=> \['foo', 'bar', 'baz'\],\
'placeholder' \=> 'Select some multiple options', // input placeholder\
'default' \=> \['foo', 'bar'\],\
\],\
\]\
\];
}
}
The `OCP\Settings\IDeclarativeSettingsForm` interface has only one method `getSchema` that should return an array with the settings schema.
After that, you can register schema class using `IRegistrationContext->registerDeclarativeSettings` method:
registerDeclarativeSettings(MyDeclarativeSettingsForm::class); }
}
Event-based schema registration[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#event-based-schema-registration "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
To register a declarative settings schema using an event system you need to implement event listener for `OCP\Settings\Events\DeclarativeSettingsRegisterFormEvent`:
registerSchema('my\_app', \[\
// your declarative settings schema here\
\]);
}
}
And register the event listener as usually in your `AppInfo/Application.php` registration context:
registerEventListener(DeclarativeSettingsRegisterFormEvent::class, RegisterDeclarativeSettingsListener::class); }
}
Handling settings storage[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#handling-settings-storage "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are two types of schema `storage_type` supported:
1\. internal `OCP\Settings\DeclarativeSettingsTypes::STORAGE_TYPE_INTERNAL` - settings values changes handled by core 1. external `OCP\Settings\DeclarativeSettingsTypes::STORAGE_TYPE_EXTERNAL` - settings values changes handled by your app handlers (event listeners).
### Internal storage type[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#internal-storage-type "Link to this heading")
Internal (`storage_type='internal'`) storage type is handled by core, you don’t have to implement additional handlers for that.
#### Section type admin[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#section-type-admin "Link to this heading")
For declarative settings schema with `section_type` set to `DeclarativeSettingsTypes::SECTION_TYPE_ADMIN` - settings values are stored in `appconfig` table.
Accessible via `OCP\IConfig->getAppValue` interface.
#### Section type personal[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#section-type-personal "Link to this heading")
For declarative settings schema with `section_type` set to `DeclarativeSettingsTypes::SECTION_TYPE_PERSONAL` - settings values are user specific and stored in `preferences` table.
Accessible via `OCP\IConfig->getUserValue` interface.
### External storage type[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#external-storage-type "Link to this heading")
Handling of an external (`storage_type='external'`) storage type is always done via listening to the following events:
1. `OCP\Settings\Events\DeclarativeSettingsGetValueEvent` - to return the declarative setting value from your storage
2. `OCP\Settings\Events\DeclarativeSettingsSetValueEvent` - to save the declarative setting value where you want to
Example of DeclarativeSettingsGetValueEvent event listener:
getApp() !== 'my\_app') {
return;
}
$value \= $this\->config\->getUserValue($event\->getUser()\->getUID(), $event\->getApp(), $event\->getFieldId()); $event\->setValue($value); }
}
Example of DeclarativeSettingsSetValueEvent event listener:
getApp() !== 'my\_app') {
return;
}
$this\->config\->setUserValue($event\->getUser()\->getUID(), $event\->getApp(), $event\->getFieldId(), $event\->getValue()); }
}
### Register get/set listeners[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#register-get-set-listeners "Link to this heading")
registerEventListener(DeclarativeSettingsGetValueEvent::class, GetDeclarativeSettingsValueListener::class); $context\->registerEventListener(DeclarativeSettingsSetValueEvent::class, SetDeclarativeSettingsValueListener::class); }
}
Schema field types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#schema-field-types "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------------------------
Supported field types are declared in `OCP\Settings\DeclarativeSettingsTypes` class:
* `DeclarativeSettingsTypes::TEXT` - input type text
* `DeclarativeSettingsTypes::PASSWORD`\- input type password
* `DeclarativeSettingsTypes::EMAIL` - input type email
* `DeclarativeSettingsTypes::TEL` - input type tel
* `DeclarativeSettingsTypes::URL` - input type url
* `DeclarativeSettingsTypes::NUMBER` - input type number
* `DeclarativeSettingsTypes::CHECKBOX` - input type checkbox
* `DeclarativeSettingsTypes::MULTI_CHECKBOX` - multiple checkboxes representing one setting with multiple options
* `DeclarativeSettingsTypes::RADIO` - input type radio for setting with single option
* `DeclarativeSettingsTypes::SELECT` - input type select for setting with single option
* `DeclarativeSettingsTypes::MULTI_SELECT` - input type select for setting with multiple options
The examples of each field type are listed below.
Note
Field order is the same as in the schema array.
### Basic input types[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#basic-input-types "Link to this heading")
For text, password, email, tel, url, number schema is similar:

\[\
'id' \=> 'my\_field\_unique\_id', // configkey\
'title' \=> 'Default text field', // label\
'description' \=> 'Set some simple text setting', // hint\
'type' \=> DeclarativeSettingsTypes::TEXT, // text, password, email, tel, url, number\
'placeholder' \=> 'Enter text setting', // placeholder\
'default' \=> 'foo',\
\],
### Checkbox and Multi-checkbox[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#checkbox-and-multi-checkbox "Link to this heading")

\[\
'id' \=> 'my\_checkbox\_field',\
'title' \=> 'Toggle something',\
'description' \=> 'Select checkbox option setting',\
'type' \=> DeclarativeSettingsTypes::CHECKBOX, // checkbox, multiple-checkbox\
'label' \=> 'Verify something if enabled',\
'default' \=> false,\
\],
\[\
'id' \=> 'my\_multicheckbox\_field',\
'title' \=> 'Multiple checkbox toggles, describing one setting, checked options are saved as an JSON object {foo: true, bar: false}',\
'description' \=> 'Select checkbox option setting',\
'type' \=> DeclarativeSettingsTypes::MULTI\_CHECKBOX, // checkbox, multi-checkbox\
'default' \=> \['foo' \=> true, 'bar' \=> true, 'baz' \=> true\],\
'options' \=> \[\
\[\
'name' \=> 'Foo',\
'value' \=> 'foo', // multiple-checkbox configkey\
\],\
\[\
'name' \=> 'Bar',\
'value' \=> 'bar',\
\],\
\[\
'name' \=> 'Baz',\
'value' \=> 'baz',\
\],\
\[\
'name' \=> 'Qux',\
'value' \=> 'qux',\
\],\
\],\
\],
### Radio[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#radio "Link to this heading")

\[\
'id' \=> 'my\_radio\_field',\
'title' \=> 'Radio toggles, describing one setting like single select',\
'description' \=> 'Select radio option setting',\
'type' \=> DeclarativeSettingsTypes::RADIO, // radio (NcCheckboxRadioSwitch type radio)\
'label' \=> 'Select single toggle',\
'default' \=> 'foo',\
'options' \=> \[\
\[\
'name' \=> 'First radio', // NcCheckboxRadioSwitch display name\
'value' \=> 'foo' // NcCheckboxRadioSwitch value\
\],\
\[\
'name' \=> 'Second radio',\
'value' \=> 'bar'\
\],\
\[\
'name' \=> 'Third radio',\
'value' \=> 'baz'\
\],\
\],\
\],
### Select and Multi-select[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#select-and-multi-select "Link to this heading")

\[\
'id' \=> 'my\_select\_field',\
'title' \=> 'Selection',\
'description' \=> 'Select some option setting',\
'type' \=> DeclarativeSettingsTypes::SELECT, // select, radio, multi-select\
'options' \=> \['foo', 'bar', 'baz'\],\
'placeholder' \=> 'Select some option setting',\
'default' \=> 'foo',\
\],

\[\
'id' \=> 'my\_multi\_select\_field', // configkey\
'title' \=> 'Multi-selection', // name or label\
'description' \=> 'Select some option setting', // hint\
'type' \=> DeclarativeSettingsTypes::MULTI\_SELECT, // select, radio, multi-select\
'options' \=> \['foo', 'bar', 'baz'\], // simple options for select, radio, multi-select\
'placeholder' \=> 'Select some multiple options', // input placeholder\
'default' \=> \['foo', 'bar'\],\
\],
### Sensitive field type[](https://docs.nextcloud.com/server/latest/developer_manual/digging_deeper/declarative_settings.html#sensitive-field-type "Link to this heading")
Since Nextcloud 32 there is a new field attribute `sensitive: true/false` available for `DeclarativeSettingsTypes::TEXT`, `DeclarativeSettingsTypes::PASSWORD` types. The values of such fields are stored in an encrypted form in the database and are not exposed to the UI.
\[\
'id' \=> 'test\_sensitive\_field',\
'title' \=> 'Sensitive text field',\
'description' \=> 'Set some secure value setting that is stored encrypted',\
'type' \=> DeclarativeSettingsTypes::TEXT,\
'label' \=> 'Sensitive field',\
'placeholder' \=> 'Set secure value',\
'default' \=> '',\
'sensitive' \=> true, // only for TEXT, PASSWORD types\
\],
\[\
'id' \=> 'test\_sensitive\_field\_2',\
'title' \=> 'Sensitive password field',\
'description' \=> 'Set some password setting that is stored encrypted',\
'type' \=> DeclarativeSettingsTypes::PASSWORD,\
'label' \=> 'Sensitive field',\
'placeholder' \=> 'Set secure value',\
'default' \=> '',\
'sensitive' \=> true, // only for TEXT, PASSWORD types\
\],

☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[32](https://docs.nextcloud.com/server/32/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
---
# App development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* App development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/index.rst)
* * *
App development[](https://docs.nextcloud.com/server/32/developer_manual/app_development/index.html#app-development "Link to this heading")
============================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html)
* [Create an app](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html#create-an-app)
* [Edit an existing app](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html#edit-an-existing-app)
* [Enable the app](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html#enable-the-app)
* [App architecture](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html#app-architecture)
* [Tutorial](https://docs.nextcloud.com/server/32/developer_manual/app_development/tutorial.html)
* [Bootstrapping](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html)
* [The Application class](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#the-application-class)
* [Bootstrapping process](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#bootstrapping-process)
* [App metadata](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html)
* [Changelog](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html#changelog)
* [Navigation and pre-app configuration](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html)
* [Adding a navigation entry](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html#adding-a-navigation-entry)
* [Initialization events](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html#initialization-events)
* [Dependency management](https://docs.nextcloud.com/server/32/developer_manual/app_development/dependency_management.html)
* [Composer](https://docs.nextcloud.com/server/32/developer_manual/app_development/dependency_management.html#composer)
* [Extending the DAV server](https://docs.nextcloud.com/server/32/developer_manual/app_development/dav_extension.html)
* [Registering a DAV plugin](https://docs.nextcloud.com/server/32/developer_manual/app_development/dav_extension.html#registering-a-dav-plugin)
* [Handling DAV events](https://docs.nextcloud.com/server/32/developer_manual/app_development/dav_extension.html#handling-dav-events)
* [Performance considerations](https://docs.nextcloud.com/server/32/developer_manual/app_development/dav_extension.html#performance-considerations)
* [Translation setup](https://docs.nextcloud.com/server/32/developer_manual/app_development/translation_setup.html)
* [Translation tool](https://docs.nextcloud.com/server/32/developer_manual/app_development/translation_setup.html#translation-tool)
* [Setup of the transifex sync](https://docs.nextcloud.com/server/32/developer_manual/app_development/translation_setup.html#setup-of-the-transifex-sync)
* [Manual translation](https://docs.nextcloud.com/server/32/developer_manual/app_development/translation_setup.html#manual-translation)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Basic concepts — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* Basic concepts
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/index.rst)
* * *
Basic concepts[](https://docs.nextcloud.com/server/32/developer_manual/basics/index.html#basic-concepts "Link to this heading")
=================================================================================================================================
* [Request lifecycle](https://docs.nextcloud.com/server/32/developer_manual/basics/request_lifecycle.html)
* [Front controller](https://docs.nextcloud.com/server/32/developer_manual/basics/request_lifecycle.html#front-controller)
* [Routing](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html)
* [OCS routes](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html#ocs-routes)
* [Extracting values from the URL](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html#extracting-values-from-the-url)
* [Matching subURLs](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html#matching-suburls)
* [Default values for subURL](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html#default-values-for-suburl)
* [Registering resources](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html#registering-resources)
* [Using the URLGenerator](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html#using-the-urlgenerator)
* [Dependency injection](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html)
* [Dependency injection](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#id2)
* [Controller injection](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#controller-injection)
* [Using a container](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#using-a-container)
* [How the container works](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#how-the-container-works)
* [Use automatic dependency assembly (recommended)](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#use-automatic-dependency-assembly-recommended)
* [Which classes should be added](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#which-classes-should-be-added)
* [Optional services](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#optional-services)
* [Accessing the container from anywhere](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#accessing-the-container-from-anywhere)
* [Controllers](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html)
* [Connecting a controller and a route](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html#connecting-a-controller-and-a-route)
* [Getting request parameters](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html#getting-request-parameters)
* [Responses](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html#responses)
* [HTML-based Responses](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html#html-based-responses)
* [Data-based responses](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html#data-based-responses)
* [Miscellaneous responses](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html#miscellaneous-responses)
* [Security considerations](https://docs.nextcloud.com/server/32/developer_manual/basics/controllers.html#security-considerations)
* [Middlewares](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html)
* [Global Middlewares](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#global-middlewares)
* [Dependency Injection Container Registration](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#dependency-injection-container-registration)
* [Parsing annotations](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#parsing-annotations)
* [Events](https://docs.nextcloud.com/server/32/developer_manual/basics/events.html)
* [Overview](https://docs.nextcloud.com/server/32/developer_manual/basics/events.html#overview)
* [OCP event dispatcher](https://docs.nextcloud.com/server/32/developer_manual/basics/events.html#ocp-event-dispatcher)
* [Hooks](https://docs.nextcloud.com/server/32/developer_manual/basics/events.html#hooks)
* [Public emitter](https://docs.nextcloud.com/server/32/developer_manual/basics/events.html#public-emitter)
* [Front-end](https://docs.nextcloud.com/server/32/developer_manual/basics/front-end/index.html)
* [Templates](https://docs.nextcloud.com/server/32/developer_manual/basics/front-end/templates.html)
* [JavaScript](https://docs.nextcloud.com/server/32/developer_manual/basics/front-end/js.html)
* [CSS](https://docs.nextcloud.com/server/32/developer_manual/basics/front-end/css.html)
* [Theming support](https://docs.nextcloud.com/server/32/developer_manual/basics/front-end/theming.html)
* [Translations](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html)
* [PHP Backend](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html#php-backend)
* [PHP Templates](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html#php-templates)
* [JavaScript / TypeScript / Vue](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html#javascript-typescript-vue)
* [ExApps (Python)](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html#exapps-python)
* [Guidelines](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html#guidelines)
* [Adding translations](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html#adding-translations)
* [Testing translations](https://docs.nextcloud.com/server/32/developer_manual/basics/translations.html#testing-translations)
* [Background jobs (Cron)](https://docs.nextcloud.com/server/32/developer_manual/basics/backgroundjobs.html)
* [Types of background jobs](https://docs.nextcloud.com/server/32/developer_manual/basics/backgroundjobs.html#types-of-background-jobs)
* [Writing a background job](https://docs.nextcloud.com/server/32/developer_manual/basics/backgroundjobs.html#writing-a-background-job)
* [Registering a background job](https://docs.nextcloud.com/server/32/developer_manual/basics/backgroundjobs.html#registering-a-background-job)
* [Caching](https://docs.nextcloud.com/server/32/developer_manual/basics/caching.html)
* [Types of caches](https://docs.nextcloud.com/server/32/developer_manual/basics/caching.html#types-of-caches)
* [In-memory cache](https://docs.nextcloud.com/server/32/developer_manual/basics/caching.html#in-memory-cache)
* [Local cache](https://docs.nextcloud.com/server/32/developer_manual/basics/caching.html#local-cache)
* [Distributed cache](https://docs.nextcloud.com/server/32/developer_manual/basics/caching.html#distributed-cache)
* [Logging](https://docs.nextcloud.com/server/32/developer_manual/basics/logging.html)
* [Admin audit logging](https://docs.nextcloud.com/server/32/developer_manual/basics/logging.html#admin-audit-logging)
* [Settings](https://docs.nextcloud.com/server/32/developer_manual/basics/setting.html)
* [Storage and database](https://docs.nextcloud.com/server/32/developer_manual/basics/storage/index.html)
* [Migrations](https://docs.nextcloud.com/server/32/developer_manual/basics/storage/migrations.html)
* [Database access](https://docs.nextcloud.com/server/32/developer_manual/basics/storage/database.html)
* [Configuration](https://docs.nextcloud.com/server/32/developer_manual/basics/storage/configuration.html)
* [Nextcloud filesystem API](https://docs.nextcloud.com/server/32/developer_manual/basics/storage/filesystem.html)
* [AppData](https://docs.nextcloud.com/server/32/developer_manual/basics/storage/appdata.html)
* [Public share template](https://docs.nextcloud.com/server/32/developer_manual/basics/public_share_template.html)
* [Testing](https://docs.nextcloud.com/server/32/developer_manual/basics/testing.html)
* [PHP](https://docs.nextcloud.com/server/32/developer_manual/basics/testing.html#php)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# ExApp development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* ExApp development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/index.rst)
* * *
ExApp development[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/index.html#exapp-development "Link to this heading")
==================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/Introduction.html)
* [Overview](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/Introduction.html#overview)
* [Glossary](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/Introduction.html#glossary)
* [Setting up dev environment](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html)
* [Install AppAPI](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#install-appapi)
* [In Place of a Conclusion](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#in-place-of-a-conclusion)
* [Development overview](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/development_overview/index.html)
* [ExApp development](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/development_overview/ExAppDevelopmentSteps.html)
* [ExApp overview](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/development_overview/ExAppOverview.html)
* [ExApp lifecycle](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/development_overview/ExAppLifecycle.html)
* [Technical details](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/index.html)
* [App Installation Flow](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/InstallationFlow.html)
* [Deployment](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/Deployment.html)
* [Authentication](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/Authentication.html)
* [Translations](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/Translations.html)
* [AppAPI Nextcloud APIs](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/api/index.html)
* [Frequently Asked Questions](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/index.html)
* [Docker Container Registry](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/DockerContainerRegistry.html)
* [Docker Socket Proxy](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/DockerSocketProxy.html)
* [GPU support](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/GpuSupport.html)
* [Scaling](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/Scaling.html)
* [Corporate Proxy - Permanent Settings for PHP CLI](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/BehindCompanyProxy.html)
* [Troubleshooting](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/faq/Troubleshooting.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Interface & interaction design — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* Interface & interaction design
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/design/index.rst)
* * *
Interface & interaction design[](https://docs.nextcloud.com/server/31/developer_manual/design/index.html#interface-interaction-design "Link to this heading")
===============================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/31/developer_manual/design/foundations.html)
* [Color](https://docs.nextcloud.com/server/31/developer_manual/design/foundations.html#color)
* [Typography](https://docs.nextcloud.com/server/31/developer_manual/design/foundations.html#typography)
* [Icons](https://docs.nextcloud.com/server/31/developer_manual/design/foundations.html#icons)
* [Naming](https://docs.nextcloud.com/server/31/developer_manual/design/foundations.html#naming)
* [Wording](https://docs.nextcloud.com/server/31/developer_manual/design/foundations.html#wording)
* [Layout](https://docs.nextcloud.com/server/31/developer_manual/design/layout.html)
* [Navigation → Content → Sidebar](https://docs.nextcloud.com/server/31/developer_manual/design/layout.html#navigation-content-sidebar)
* [Navigation → List → Content](https://docs.nextcloud.com/server/31/developer_manual/design/layout.html#navigation-list-content)
* [Layout components](https://docs.nextcloud.com/server/31/developer_manual/design/layoutcomponents.html)
* [Navigation](https://docs.nextcloud.com/server/31/developer_manual/design/layoutcomponents.html#navigation)
* [List item](https://docs.nextcloud.com/server/31/developer_manual/design/layoutcomponents.html#list-item)
* [Content](https://docs.nextcloud.com/server/31/developer_manual/design/layoutcomponents.html#content)
* [Sidebar](https://docs.nextcloud.com/server/31/developer_manual/design/layoutcomponents.html#sidebar)
* [Atomic components](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html)
* [Buttons](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#buttons)
* [Action menu](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#action-menu)
* [Input fields](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#input-fields)
* [Pickers](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#pickers)
* [Tags](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#tags)
* [Modal](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#modal)
* [Avatar](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#avatar)
* [Progress bars and meters](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#progress-bars-and-meters)
* [User bubbles](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#user-bubbles)
* [Counter bubbles](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#counter-bubbles)
* [Empty content](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#empty-content)
* [Skeleton screens](https://docs.nextcloud.com/server/31/developer_manual/design/atomiccomponents.html#skeleton-screens)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Server development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* Server development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/index.rst)
* * *
Server development[](https://docs.nextcloud.com/server/stable/developer_manual/server/index.html#server-development "Link to this heading")
=============================================================================================================================================
Please make sure you have set up a [Development environment](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/devenv.html#devenv)
.
* [Front-end code](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html)
* [Building Vue components and scripts](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html#building-vue-components-and-scripts)
* [Building styles](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html#building-styles)
* [Committing changes](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html#committing-changes)
* [Back-end code](https://docs.nextcloud.com/server/stable/developer_manual/server/code-back-end.html)
* [Compatibility documentation](https://docs.nextcloud.com/server/stable/developer_manual/server/code-back-end.html#compatibility-documentation)
* [Static analysis](https://docs.nextcloud.com/server/stable/developer_manual/server/static-analysis.html)
* [PHP static analysis](https://docs.nextcloud.com/server/stable/developer_manual/server/static-analysis.html#php-static-analysis)
* [Unit-Testing](https://docs.nextcloud.com/server/stable/developer_manual/server/unit-testing.html)
* [PHP unit testing](https://docs.nextcloud.com/server/stable/developer_manual/server/unit-testing.html#php-unit-testing)
* [JavaScript unit testing for server](https://docs.nextcloud.com/server/stable/developer_manual/server/unit-testing.html#javascript-unit-testing-for-server)
* [External API](https://docs.nextcloud.com/server/stable/developer_manual/server/externalapi.html)
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/server/externalapi.html#introduction)
* [Usage](https://docs.nextcloud.com/server/stable/developer_manual/server/externalapi.html#usage)
* [Nextcloud architecture](https://docs.nextcloud.com/server/stable/developer_manual/server/architecture/index.html)
* [Nextcloud filesystem API](https://docs.nextcloud.com/server/stable/developer_manual/server/architecture/files.html)
* [How to test …](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html)
* [Email sending](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#email-sending)
* [Redis](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#redis)
* [Redis Cluster](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#redis-cluster)
* [Primary object store with S3](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#primary-object-store-with-s3)
* [S3 external storage](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#s3-external-storage)
* [SMB external storage](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#smb-external-storage)
* [SAML setup with onelogin](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#saml-setup-with-onelogin)
* [Collabora without SSL](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#collabora-without-ssl)
* [OnlyOffice](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#onlyoffice)
* [WebAuthn without SSL](https://docs.nextcloud.com/server/stable/developer_manual/how_to/index.html#webauthn-without-ssl)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# App publishing and maintenance — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* App publishing and maintenance
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_publishing_maintenance/index.rst)
* * *
App publishing and maintenance[](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/index.html#app-publishing-and-maintenance "Link to this heading")
=====================================================================================================================================================================================
Transforming source files into a deliverable is documented in the [Release process](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html#app-release-process)
.
* [Maintainers](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/maintainer.html)
* [Release process](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html)
* [Overview](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html#overview)
* [Before the release](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html#before-the-release)
* [The release](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html#the-release)
* [After the release](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html#after-the-release)
* [Shipped Apps](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_process.html#shipped-apps)
* [Publishing App on the App Store](https://nextcloudappstore.readthedocs.io/en/latest/developer.html)
* [Monetizing your app](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/monetizing.html)
* [Donations](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/monetizing.html#donations)
* [Enterprise support](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/monetizing.html#enterprise-support)
* [The Nextcloud app store rules](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/publishing.html)
* [Losing a rating](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/publishing.html#losing-a-rating)
* [App guidelines](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/publishing.html#app-guidelines)
* [Moving your repo to the Nextcloud organization](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/publishing.html#moving-your-repo-to-the-nextcloud-organization)
* [Code signing](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/code_signing.html)
* [FAQ](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/code_signing.html#faq)
* [Technical details](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/code_signing.html#technical-details)
* [How code signing affects apps in the app store](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/code_signing.html#how-code-signing-affects-apps-in-the-app-store)
* [How to get your app signed](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/code_signing.html#how-to-get-your-app-signed)
* [Errors](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/code_signing.html#errors)
* [Release Automation](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_automation.html)
* [GitHub Actions](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/release_automation.html#github-actions)
* [App upgrade guide](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html)
* [Upgrade to Nextcloud 31](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.html)
* [Upgrade to Nextcloud 30](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_30.html)
* [Upgrade to Nextcloud 29](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_29.html)
* [Upgrade to Nextcloud 28](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_28.html)
* [Upgrade to Nextcloud 27](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_27.html)
* [Upgrade to Nextcloud 26](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_26.html)
* [Upgrade to Nextcloud 25](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_25.html)
* [Upgrade to Nextcloud 24](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_24.html)
* [Upgrade to Nextcloud 23](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_23.html)
* [Upgrade to Nextcloud 22](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_22.html)
* [Upgrade to Nextcloud 21](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_21.html)
* [Upgrade to Nextcloud 20](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_20.html)
* [Upgrade to Nextcloud 19](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_19.html)
* [Upgrade to Nextcloud 18](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_18.html)
* [Upgrade to Nextcloud 17](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_17.html)
* [Upgrade to Nextcloud 16](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_16.html)
* [Upgrade to Nextcloud 15](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_15.html)
* [Upgrade to Nextcloud 14](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_14.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Server development — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* Server development
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/index.rst)
* * *
Server development[](https://docs.nextcloud.com/server/32/developer_manual/server/index.html#server-development "Link to this heading")
=========================================================================================================================================
Please make sure you have set up a [Development environment](https://docs.nextcloud.com/server/32/developer_manual/getting_started/devenv.html#devenv)
.
* [Front-end code](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html)
* [Building Vue components and scripts](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html#building-vue-components-and-scripts)
* [Building styles](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html#building-styles)
* [Committing changes](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html#committing-changes)
* [Back-end code](https://docs.nextcloud.com/server/32/developer_manual/server/code-back-end.html)
* [Compatibility documentation](https://docs.nextcloud.com/server/32/developer_manual/server/code-back-end.html#compatibility-documentation)
* [Static analysis](https://docs.nextcloud.com/server/32/developer_manual/server/static-analysis.html)
* [PHP static analysis](https://docs.nextcloud.com/server/32/developer_manual/server/static-analysis.html#php-static-analysis)
* [Unit-Testing](https://docs.nextcloud.com/server/32/developer_manual/server/unit-testing.html)
* [PHP unit testing](https://docs.nextcloud.com/server/32/developer_manual/server/unit-testing.html#php-unit-testing)
* [JavaScript unit testing for server](https://docs.nextcloud.com/server/32/developer_manual/server/unit-testing.html#javascript-unit-testing-for-server)
* [External API](https://docs.nextcloud.com/server/32/developer_manual/server/externalapi.html)
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/server/externalapi.html#introduction)
* [Usage](https://docs.nextcloud.com/server/32/developer_manual/server/externalapi.html#usage)
* [Nextcloud architecture](https://docs.nextcloud.com/server/32/developer_manual/server/architecture/index.html)
* [Nextcloud filesystem API](https://docs.nextcloud.com/server/32/developer_manual/server/architecture/files.html)
* [How to test …](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html)
* [Email sending](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#email-sending)
* [Redis](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#redis)
* [Redis Cluster](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#redis-cluster)
* [Primary object store with S3](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#primary-object-store-with-s3)
* [S3 external storage](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#s3-external-storage)
* [SMB external storage](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#smb-external-storage)
* [SAML setup with onelogin](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#saml-setup-with-onelogin)
* [Collabora without SSL](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#collabora-without-ssl)
* [OnlyOffice](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#onlyoffice)
* [WebAuthn without SSL](https://docs.nextcloud.com/server/32/developer_manual/how_to/index.html#webauthn-without-ssl)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Interface & interaction design — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* Interface & interaction design
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/design/index.rst)
* * *
Interface & interaction design[](https://docs.nextcloud.com/server/stable/developer_manual/design/index.html#interface-interaction-design "Link to this heading")
===================================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/stable/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/stable/developer_manual/design/foundations.html)
* [Color](https://docs.nextcloud.com/server/stable/developer_manual/design/foundations.html#color)
* [Typography](https://docs.nextcloud.com/server/stable/developer_manual/design/foundations.html#typography)
* [Icons](https://docs.nextcloud.com/server/stable/developer_manual/design/foundations.html#icons)
* [Naming](https://docs.nextcloud.com/server/stable/developer_manual/design/foundations.html#naming)
* [Wording](https://docs.nextcloud.com/server/stable/developer_manual/design/foundations.html#wording)
* [Layout](https://docs.nextcloud.com/server/stable/developer_manual/design/layout.html)
* [Navigation → Content → Sidebar](https://docs.nextcloud.com/server/stable/developer_manual/design/layout.html#navigation-content-sidebar)
* [Navigation → List → Content](https://docs.nextcloud.com/server/stable/developer_manual/design/layout.html#navigation-list-content)
* [Layout components](https://docs.nextcloud.com/server/stable/developer_manual/design/layoutcomponents.html)
* [Navigation](https://docs.nextcloud.com/server/stable/developer_manual/design/layoutcomponents.html#navigation)
* [List item](https://docs.nextcloud.com/server/stable/developer_manual/design/layoutcomponents.html#list-item)
* [Content](https://docs.nextcloud.com/server/stable/developer_manual/design/layoutcomponents.html#content)
* [Sidebar](https://docs.nextcloud.com/server/stable/developer_manual/design/layoutcomponents.html#sidebar)
* [Atomic components](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html)
* [Buttons](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#buttons)
* [Action menu](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#action-menu)
* [Input fields](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#input-fields)
* [Pickers](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#pickers)
* [Tags](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#tags)
* [Modal](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#modal)
* [Avatar](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#avatar)
* [Progress bars and meters](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#progress-bars-and-meters)
* [User bubbles](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#user-bubbles)
* [Counter bubbles](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#counter-bubbles)
* [Empty content](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#empty-content)
* [Skeleton screens](https://docs.nextcloud.com/server/stable/developer_manual/design/atomiccomponents.html#skeleton-screens)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Code of conduct — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/31/developer_manual/prologue/index.html)
* Code of conduct
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/code-of-conduct.rst)
* * *
Code of conduct[](https://docs.nextcloud.com/server/31/developer_manual/prologue/code-of-conduct.html#code-of-conduct "Link to this heading")
===============================================================================================================================================
We want the Nextcloud community to be a fun and productive environment for everyone. For that reason, we ask all contributors and participants to familiarize themselves with our [Code of Conduct](https://nextcloud.com/code-of-conduct)
.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# App publishing and maintenance — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* App publishing and maintenance
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_publishing_maintenance/index.rst)
* * *
App publishing and maintenance[](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/index.html#app-publishing-and-maintenance "Link to this heading")
=========================================================================================================================================================================================
Transforming source files into a deliverable is documented in the [Release process](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html#app-release-process)
.
* [Maintainers](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/maintainer.html)
* [Release process](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html)
* [Overview](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html#overview)
* [Before the release](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html#before-the-release)
* [The release](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html#the-release)
* [After the release](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html#after-the-release)
* [Shipped Apps](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html#shipped-apps)
* [Publishing App on the App Store](https://nextcloudappstore.readthedocs.io/en/latest/developer.html)
* [Monetizing your app](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/monetizing.html)
* [Donations](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/monetizing.html#donations)
* [Enterprise support](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/monetizing.html#enterprise-support)
* [The Nextcloud app store rules](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/publishing.html)
* [Losing a rating](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/publishing.html#losing-a-rating)
* [App guidelines](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/publishing.html#app-guidelines)
* [Moving your repo to the Nextcloud organization](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/publishing.html#moving-your-repo-to-the-nextcloud-organization)
* [Code signing](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/code_signing.html)
* [FAQ](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/code_signing.html#faq)
* [Technical details](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/code_signing.html#technical-details)
* [How code signing affects apps in the app store](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/code_signing.html#how-code-signing-affects-apps-in-the-app-store)
* [How to get your app signed](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/code_signing.html#how-to-get-your-app-signed)
* [Errors](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/code_signing.html#errors)
* [Release Automation](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_automation.html)
* [GitHub Actions](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_automation.html#github-actions)
* [App upgrade guide](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html)
* [Upgrade to Nextcloud 32](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_32.html)
* [Upgrade to Nextcloud 31](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.html)
* [Upgrade to Nextcloud 30](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_30.html)
* [Upgrade to Nextcloud 29](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_29.html)
* [Upgrade to Nextcloud 28](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_28.html)
* [Upgrade to Nextcloud 27](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_27.html)
* [Upgrade to Nextcloud 26](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_26.html)
* [Upgrade to Nextcloud 25](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_25.html)
* [Upgrade to Nextcloud 24](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_24.html)
* [Upgrade to Nextcloud 23](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_23.html)
* [Upgrade to Nextcloud 22](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_22.html)
* [Upgrade to Nextcloud 21](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_21.html)
* [Upgrade to Nextcloud 20](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_20.html)
* [Upgrade to Nextcloud 19](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_19.html)
* [Upgrade to Nextcloud 18](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_18.html)
* [Upgrade to Nextcloud 17](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_17.html)
* [Upgrade to Nextcloud 16](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_16.html)
* [Upgrade to Nextcloud 15](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_15.html)
* [Upgrade to Nextcloud 14](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_14.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Interface & interaction design — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* Interface & interaction design
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/design/index.rst)
* * *
Interface & interaction design[](https://docs.nextcloud.com/server/32/developer_manual/design/index.html#interface-interaction-design "Link to this heading")
===============================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/32/developer_manual/design/introduction.html)
* [Foundations](https://docs.nextcloud.com/server/32/developer_manual/design/foundations.html)
* [Color](https://docs.nextcloud.com/server/32/developer_manual/design/foundations.html#color)
* [Typography](https://docs.nextcloud.com/server/32/developer_manual/design/foundations.html#typography)
* [Icons](https://docs.nextcloud.com/server/32/developer_manual/design/foundations.html#icons)
* [Naming](https://docs.nextcloud.com/server/32/developer_manual/design/foundations.html#naming)
* [Wording](https://docs.nextcloud.com/server/32/developer_manual/design/foundations.html#wording)
* [Layout](https://docs.nextcloud.com/server/32/developer_manual/design/layout.html)
* [Navigation → Content → Sidebar](https://docs.nextcloud.com/server/32/developer_manual/design/layout.html#navigation-content-sidebar)
* [Navigation → List → Content](https://docs.nextcloud.com/server/32/developer_manual/design/layout.html#navigation-list-content)
* [Layout components](https://docs.nextcloud.com/server/32/developer_manual/design/layoutcomponents.html)
* [Navigation](https://docs.nextcloud.com/server/32/developer_manual/design/layoutcomponents.html#navigation)
* [List item](https://docs.nextcloud.com/server/32/developer_manual/design/layoutcomponents.html#list-item)
* [Content](https://docs.nextcloud.com/server/32/developer_manual/design/layoutcomponents.html#content)
* [Sidebar](https://docs.nextcloud.com/server/32/developer_manual/design/layoutcomponents.html#sidebar)
* [Atomic components](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html)
* [Buttons](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#buttons)
* [Action menu](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#action-menu)
* [Input fields](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#input-fields)
* [Pickers](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#pickers)
* [Tags](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#tags)
* [Modal](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#modal)
* [Avatar](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#avatar)
* [Progress bars and meters](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#progress-bars-and-meters)
* [User bubbles](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#user-bubbles)
* [Counter bubbles](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#counter-bubbles)
* [Empty content](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#empty-content)
* [Skeleton screens](https://docs.nextcloud.com/server/32/developer_manual/design/atomiccomponents.html#skeleton-screens)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Help and communication — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/31/developer_manual/prologue/index.html)
* Help and communication
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/help_communication.rst)
* * *
Help and communication[](https://docs.nextcloud.com/server/31/developer_manual/prologue/help_communication.html#help-and-communication "Link to this heading")
================================================================================================================================================================
Forums[](https://docs.nextcloud.com/server/31/developer_manual/prologue/help_communication.html#forums "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------
Communicate via our [forums](https://help.nextcloud.com/)
.
Maintainers[](https://docs.nextcloud.com/server/31/developer_manual/prologue/help_communication.html#maintainers "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------
* [Contact](https://nextcloud.com/contact/)
a maintainer of a certain app or division
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Bugtracker — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/31/developer_manual/prologue/index.html)
* Bugtracker
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/bugtracker/index.rst)
* * *
Bugtracker[](https://docs.nextcloud.com/server/31/developer_manual/prologue/bugtracker/index.html#bugtracker "Link to this heading")
======================================================================================================================================
Thank you for helping Nextcloud by reporting bugs. Before submitting an issue, please read [Issue submission guidelines](https://github.com/nextcloud/server/blob/master/.github/CONTRIBUTING.md#submitting-issues)
first.
* If the issue is with the Nextcloud server, report it to the [Server repository](https://github.com/nextcloud/server/issues)
* If the issue is with the Nextcloud desktop client, report it to the [Desktop repository](https://github.com/nextcloud/desktop/issues)
* If the issue is with the Nextcloud Android client, report it to the [Android repository](https://github.com/nextcloud/android/issues)
* If the issue is with the Nextcloud iOS client, report it to the [iOS repository](https://github.com/nextcloud/ios/issues)
* If the issue is with a Nextcloud app, report it to where that app is developed. See [App Store](https://apps.nextcloud.com/)
page for related links.
* If the app is listed in our [main GitHub organization](https://github.com/nextcloud)
report it to the correct sub repository
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# HTML/CSS guidelines — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* HTML/CSS guidelines
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/html_css_design/index.rst)
* * *
HTML/CSS guidelines[](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/index.html#html-css-guidelines "Link to this heading")
====================================================================================================================================================
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html)
* [New button](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#new-button)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#id1)
* [Basic layout](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#basic-layout)
* [Rules](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#rules)
* [App navigation menu](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#app-navigation-menu)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#id2)
* [Basic layout](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#id3)
* [Basic rules](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#basic-rules)
* [Utils: menu, counter & buttons](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#utils-menu-counter-buttons)
* [Drag and drop](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#drag-and-drop)
* [Collapsible entry](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#collapsible-entry)
* [Entry bullet](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#entry-bullet)
* [Undo entry](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#undo-entry)
* [Edit entry](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#edit-entry)
* [Pinned entry](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#pinned-entry)
* [Various information](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#various-information)
* [Settings](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#settings)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#id4)
* [Basic layout](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/navigation.html#id5)
* [Main content](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/content.html)
* [Rules and information](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/content.html#rules-and-information)
* [Content list](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/list.html)
* [Introduction](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/list.html#introduction)
* [Basic layout](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/list.html#basic-layout)
* [Rules and information](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/list.html#rules-and-information)
* [Popovermenu in item](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/list.html#popovermenu-in-item)
* [Popover menu](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/popovermenu.html)
* [What is a popover menu](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/popovermenu.html#what-is-a-popover-menu)
* [Basic layout](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/popovermenu.html#basic-layout)
* [Technical details](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/popovermenu.html#technical-details)
* [Alignment](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/popovermenu.html#alignment)
* [HTML elements](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/html.html)
* [Progress bar](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/html.html#progress-bar)
* [Checkboxes and radios](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/html.html#checkboxes-and-radios)
* [Buttons](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/html.html#buttons)
* [CSS](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/css.html)
* [CSS variables](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/css.html#css-variables)
* [CSS classes](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/css.html#css-classes)
* [Icons](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/icons.html)
* [List of available icons](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/icons.html#list-of-available-icons)
* [Svg color api](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/icons.html#svg-color-api)
* [Material design icons](https://docs.nextcloud.com/server/31/developer_manual/html_css_design/icons.html#material-design-icons)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Development process — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Getting started](https://docs.nextcloud.com/server/31/developer_manual/getting_started/index.html)
* Development process
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/getting_started/development_process.rst)
* * *
Development process[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#development-process "Link to this heading")
==================================================================================================================================================================
This page gives an overview of how Nextcloud code is developed.
Source Code Version Control[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#source-code-version-control "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Nextcloud uses [git](https://git-scm.com/)
to manage revisions of the code. Software components have their own repositories.
### Branch Names[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#branch-names "Link to this heading")
Default branches of Nextcloud and its app repositories are named `main` or `master`. Additionally, there are _stable branches_ whenever a major version of Nextcloud is released. Those are named `stableX`, where X refers to the version. For Nextcloud 25, for example, the stable branch is named `stable25`.
Target Branches for Contributions[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#target-branches-for-contributions "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Any changes made to the source code go into the default branch of a repository through a [pull request](https://docs.github.com/en/pull-requests)
.
\# Switch to the default branch and update it
git checkout main
git pull origin main
\# Create the new feature branch
git checkout \-b feature/foo-bar
\# Add and commit the changes
git add file1 file2
git commit \--signoff \-m 'Add foo bar'
\# Push the new commit to the remote repository and open a pull request
git push origin feature/foo-bar
### Bugfixes[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#bugfixes "Link to this heading")
If a contribution fixes a bug that also affects older Nextcloud or app releases, it may qualify for a _backport_. Backporting a fix means applying the change on an older version of the code. Git calls this operation _cherry picking_.
#### Automatic Backport[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#automatic-backport "Link to this heading")
In many cases the cherry pick results in a clean apply of the patch and git is able to resolve any small conflicts. In those cases it’s easiest to let the [backport bot](https://github.com/nextcloud/backportbot)
do the backport.
See the [bot usage](https://github.com/nextcloud/backportbot#usage)
for its commands.
#### Manual Backport[](https://docs.nextcloud.com/server/31/developer_manual/getting_started/development_process.html#manual-backport "Link to this heading")
More complex changes may require the developer to do the backport manually. This can be done as follows:
\# Switch to the target branch and update it
git checkout stable25
git pull origin stable25
\# Create the new backport branch
git checkout \-b fix/foo-stable25
\# Cherry pick the change from the commit sha1 of the change against the default branch
\# This might cause conflicts. Resolve them.
git cherry-pick abc123
\# Push the cherry pick commit to the remote repository and open a pull request
git push origin fix/foo-stable25
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# App publishing and maintenance — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* App publishing and maintenance
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_publishing_maintenance/index.rst)
* * *
App publishing and maintenance[](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/index.html#app-publishing-and-maintenance "Link to this heading")
=====================================================================================================================================================================================
Transforming source files into a deliverable is documented in the [Release process](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html#app-release-process)
.
* [Maintainers](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/maintainer.html)
* [Release process](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html)
* [Overview](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html#overview)
* [Before the release](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html#before-the-release)
* [The release](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html#the-release)
* [After the release](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html#after-the-release)
* [Shipped Apps](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html#shipped-apps)
* [Publishing App on the App Store](https://nextcloudappstore.readthedocs.io/en/latest/developer.html)
* [Monetizing your app](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/monetizing.html)
* [Donations](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/monetizing.html#donations)
* [Enterprise support](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/monetizing.html#enterprise-support)
* [The Nextcloud app store rules](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/publishing.html)
* [Losing a rating](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/publishing.html#losing-a-rating)
* [App guidelines](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/publishing.html#app-guidelines)
* [Moving your repo to the Nextcloud organization](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/publishing.html#moving-your-repo-to-the-nextcloud-organization)
* [Code signing](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/code_signing.html)
* [FAQ](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/code_signing.html#faq)
* [Technical details](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/code_signing.html#technical-details)
* [How code signing affects apps in the app store](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/code_signing.html#how-code-signing-affects-apps-in-the-app-store)
* [How to get your app signed](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/code_signing.html#how-to-get-your-app-signed)
* [Errors](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/code_signing.html#errors)
* [Release Automation](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_automation.html)
* [GitHub Actions](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_automation.html#github-actions)
* [App upgrade guide](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html)
* [Upgrade to Nextcloud 32](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_32.html)
* [Upgrade to Nextcloud 31](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_31.html)
* [Upgrade to Nextcloud 30](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_30.html)
* [Upgrade to Nextcloud 29](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_29.html)
* [Upgrade to Nextcloud 28](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_28.html)
* [Upgrade to Nextcloud 27](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_27.html)
* [Upgrade to Nextcloud 26](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_26.html)
* [Upgrade to Nextcloud 25](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_25.html)
* [Upgrade to Nextcloud 24](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_24.html)
* [Upgrade to Nextcloud 23](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_23.html)
* [Upgrade to Nextcloud 22](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_22.html)
* [Upgrade to Nextcloud 21](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_21.html)
* [Upgrade to Nextcloud 20](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_20.html)
* [Upgrade to Nextcloud 19](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_19.html)
* [Upgrade to Nextcloud 18](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_18.html)
* [Upgrade to Nextcloud 17](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_17.html)
* [Upgrade to Nextcloud 16](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_16.html)
* [Upgrade to Nextcloud 15](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_15.html)
* [Upgrade to Nextcloud 14](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/upgrade_to_14.html)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Code of conduct — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/stable/developer_manual/prologue/index.html)
* Code of conduct
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/code-of-conduct.rst)
* * *
Code of conduct[](https://docs.nextcloud.com/server/stable/developer_manual/prologue/code-of-conduct.html#code-of-conduct "Link to this heading")
===================================================================================================================================================
We want the Nextcloud community to be a fun and productive environment for everyone. For that reason, we ask all contributors and participants to familiarize themselves with our [Code of Conduct](https://nextcloud.com/code-of-conduct)
.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Compatibility with the app ecosystem — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/31/developer_manual/prologue/index.html)
* Compatibility with the app ecosystem
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/compatibility_app_ecosystem.rst)
* * *
Compatibility with the app ecosystem[](https://docs.nextcloud.com/server/31/developer_manual/prologue/compatibility_app_ecosystem.html#compatibility-with-the-app-ecosystem "Link to this heading")
=====================================================================================================================================================================================================
The Nextcloud app ecosystem consists of hundreds of apps and app maintainers.
The development process may require changes that affect apps in this ecosystem. These changes may either be a change in standards or best practises, yet in more extreme cases the changes may also be breaking apps.
While developers are expected to aim for limiting the number of changes that break apps, this cannot always be avoided or is not always reasonable to do to maintain an up-to-date technology stack.
Informing app developers about any change that affect them is therefore key to a thriving ecosystem. This page describes the three procedures to document changes that are relevant to app developers.
Documentation procedures of changes that affect app developers[](https://docs.nextcloud.com/server/31/developer_manual/prologue/compatibility_app_ecosystem.html#documentation-procedures-of-changes-that-affect-app-developers "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are three procedures in place to facilitate communication to app developers about changes that affect them:
1. The definition of **Done** of a pull request includes documentation.
> This means the development of your pull request cannot be considered done if you introduced changes (additions, removals or modifications) that affect app developers that you did not document.
2. A change that affects app developers, has to be reported and documented by the author of the pull request in the [App Upgrade guide](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html#app-upgrade-guide)
section.
> The requirements for this documentation are:
>
> * It should be written so that app developers understand how to work around the change for their app in a tutorial format
>
> * The steps should be explicitly written, so the documentation shall not rely upon links to external resources for the steps. While it is encouraged to add an external links as additional reference, it is a hard requirement that the documentation is readable and actionable without browsing to this link.
>
> * The change author’s name should be added to the section so readers can reach out to the author if they have questions or if something is unclear.
>
> * Timeline: the documentation is required to be handed in when finalizing the pull request and should be merged timely close to the actual change.
>
Other documentation requirements[](https://docs.nextcloud.com/server/31/developer_manual/prologue/compatibility_app_ecosystem.html#other-documentation-requirements "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
A change that affects administrators who upgrade their Nextcloud should be documented in the release notes section of the admin documentation of that release.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Security guidelines — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Prologue](https://docs.nextcloud.com/server/31/developer_manual/prologue/index.html)
* Security guidelines
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/prologue/security.rst)
* * *
Security guidelines[](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#security-guidelines "Link to this heading")
================================================================================================================================================
This guideline highlights some of the most common security problems and how to prevent them. Please review your app if it contains any of the following security holes.
Note
**Program defensively**: for instance always check for CSRF or escape strings, even if you do not need it. This prevents future problems where you might miss a change that leads to a security hole.
Note
All App Framework security features depend on the call of the controller through `OCA\AppFramework\App::main`. If the controller method is executed directly, no security checks are being performed!
SQL injection[](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#sql-injection "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------
[SQL Injection](https://en.wikipedia.org/wiki/SQL_injection)
occurs when SQL query strings are concatenated with variables.
To prevent this, always use prepared queries:
execute($params);
If the App Framework is used, write SQL queries like this in a class that extends the Mapper:
execute($sql, $params);
Cross site scripting[](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#cross-site-scripting "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
[Cross site scripting](https://en.wikipedia.org/wiki/Cross-site_scripting)
happens when user input is passed directly to templates. A potential attacker might be able to inject HTML/JavaScript into the page to steal the users session, log keyboard entries, even perform DDOS attacks on other websites or other malicious actions.
Despite the fact that Nextcloud uses Content-Security-Policy to prevent the execution of inline JavaScript code developers are still required to prevent XSS. CSP is just another layer of defense that is not implemented in all web browsers.
To prevent XSS in your app you have to sanitize the templates and all JavaScripts which performs a DOM manipulation.
### Templates[](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#templates "Link to this heading")
Let’s assume you use the following example in your application:
to overtake the user account. The same problem occurs when outputting content from the database or any other location that is writable by users.
Another attack vector that is often overlooked is XSS in **href** attributes. HTML allows to execute JavaScript in href attributes like this:
To prevent XSS in your app, **never use echo, print() or <%=** - use **p()** instead which will sanitize the input. Also **validate URLs to start with the expected protocol** (starts with http for instance)!
Note
Should you ever require to print something unescaped, double check if it is really needed. If there is no other way (e.g. when including of subtemplates) use print\_unescaped with care.
### JavaScript[](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#javascript "Link to this heading")
Avoid manipulating the HTML directly via JavaScript, this often leads to XSS since people often forget to sanitize variables:
var html \= '
Add a space before the triple-dot when trimming a sentence instead of a word. |
| Don’t | Do not | Using the spelled out version is easier to understand and makes translating easier. |
| Won’t | Will not | Using the spelled out version is easier to understand and makes translating easier. |
| Can not | Cannot | Using the combined version is easier to understand and makes translating easier. |
| id | ID | Full uppercase for shortcutting “identifier” |
| Users | Accounts / People | Use **accounts** when you refer to a profile/entity. Use **people** when referring to humans. |
| Admin / Administrator | Administration | Refer to administration as a non-human organizational entity
instead of a single or multiple persons. |
| Headline | Headline: | Include colons `:` in the translations as some languages add a space before the colon. |
| “ Leading space”
“Trailing space “ | “No leading space”
“No trailing space” | Leading or trailing spaces mostly indicate that strings are concatenated.
For translators it is often helpful to have all the content in a single translation,
as order and references between words and sentences might get lost otherwise. |
| “Error:” $error | “Error: %s” | Instead of concatenating errors or part messages, make them a proper placeholder |
### Correct plurals[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#correct-plurals "Link to this heading")
If you use a plural, you **must** also use the `%n` placeholder. The placeholder defines the plural and the word without the number preceding is wrong. If you don’t know/have a number for your translation, e.g. because you don’t know how many items are going to be selected, just use an undefined plural. They exist in every language and have one form. They do not follow the normal plural pattern.
PHP Example:
// BAD: Plural without count
$title \= $l\->n('Import calendar', 'Import calendars', $selectionLength)
// BETTER: Plural has count, but disrupting to read and unnecessary information
$title \= $l\->n('Import %n calendar', 'Import %n calendars', $selectionLength)
// BEST: Simple string with undefined plural not using any number in the string
$title \= $l\->t('Import calendars')
Opposed to the normal placeholders in javascript, the plural number also uses the `%n` syntax:
JS Example:
/\* BAD: Plural without count \*/
n('myapp', 'Import calendar', 'Import calendars', selected.length)
/\* BETTER: Plural has count, but disrupting to read and unnecessary information \*/
n('myapp', 'Import %n calendar', 'Import %n calendars', selected.length)
/\* BEST: Simple string with undefined plural not using any number in the string \*/
t('myapp', 'Import calendars')
### Improving your translations[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#improving-your-translations "Link to this heading")
Starting with the following example, improving it step by step:
t('Select file from')) . ' '; ?>t('local filesystem'));?>t(' or ')); ?>t('cloud'));?>
#### Step 1: String split[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#step-1-string-split "Link to this heading")
You shall **never split** sentences and **never concatenate** two translations (e.g. “Enable” and “dark mode” can not be combined to “Enable dark mode”, because languages might have to use different cases)! Translators lose the context and they have no chance to possibly re-arrange words/parts as needed.
Translators will translate:
* `Select file from`
* `local filesystem`
* `or` (with leading and trailing whitespace)
* `cloud`
Translating these individual strings results in `local filesystem` and `cloud` losing case. The two white spaces surrounding `or` will get lost while translating as well. For languages that have a different grammatical order it prevents the translators from reordering the sentence components.
So the following code is a bit better, but suffers from another issue:
t('Select file from local filesystem or cloud'));?>
#### Step 2: HTML Markup[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#step-2-html-markup "Link to this heading")
In this case the translators can re-arrange as they like, but have to deal with your markup and can mess it up easily. It is better to **keep the markup out** of your code, so the following translation is even better:
t('Select file from %slocal filesystem%s or %scloud%s', \['', '', '', ''\]));?>
But there is one last problem with this.
#### Step 3: Placeholders[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#step-3-placeholders "Link to this heading")
In case the language has to turn things around, your code will still insert the parameters in the given order and they can not re-order them. To prevent this last hurdle simply **use positioned placeholders** like `%1$s`:
t('Select file from %1$slocal filesystem%2$s or %3$scloud%4$s', \['', '', '', ''\]));?>
This allows translators to have the cloudlink before the browselink in case the language is e.g. right-to-left.
### Provide context hints for translators[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#provide-context-hints-for-translators "Link to this heading")
In case some translation strings may be translated wrongly because they have multiple meanings. Especially translations strings that only contain a single word often result in problems. The most famous example in the Nextcloud code base is `Share` which can which can be the verb and action `To share something` or the noun `A share`. The added hints will be shown in the Transifex web-interface:
#### PHP[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#php "Link to this heading")
t('Add new file'));
?>
#### JavaScript / TypeScript[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#javascript-typescript "Link to this heading")
// TRANSLATORS name that is appended to copied files with the same name, will be put in parenthesis and appended with a number if it is the second+ copy
var copyNameLocalized \= t('files', 'copy');
#### Vue[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#vue "Link to this heading")
This covers vue html templates in vue sfc components. For vue js code, see the javascript section.
{{ t('forms', 'Required') }}
#### C++ (Qt) / Desktop client[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#c-qt-desktop-client "Link to this heading")
//: Example text: "Progress of sync process. Shows the currently synced filename"
fileProgressString \= tr("Syncing %1").arg(allFilenames);
#### Android[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#android "Link to this heading")
Boards
#### iOS[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#ios "Link to this heading")
/\* The title on the navigation bar of the Scanning screen. \*/
"wescan.scanning.title" \= "Scanning";
Adding translations[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#adding-translations "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
The steps how to set up translations for an app have been moved to it’s own page in the “App development” chapter: [Translation setup](https://docs.nextcloud.com/server/31/developer_manual/app_development/translation_setup.html#translation-setup)
Testing translations[](https://docs.nextcloud.com/server/31/developer_manual/basics/translations.html#testing-translations "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------
You can use the query parameter `forceLanguage` to force a specific language for a web request (API or frontend). See [Forcing language for a given call](https://docs.nextcloud.com/server/31/developer_manual/client_apis/OCS/ocs-api-overview.html#api-force-language)
.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Bootstrapping — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html)
* Bootstrapping
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/bootstrap.rst)
* * *
Bootstrapping[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#bootstrapping "Link to this heading")
================================================================================================================================================
Every php process has a relatively short lifespan that lasts as long as the HTTP request or the invocation of the command line program. At the beginning of this lifespan, Nextcloud initializes its services. At the same time, any additional apps might want to register their services to Nextcloud as well. This event is called the _bootstrapping_ and this chapter shall shed some light on how to hook into this with an app.
The Application class[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#the-application-class "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
The Application class is the main entry point of an app. This class is optional but highly recommended if your app needs to register any services or run some code for every request.
Nextcloud will try to autoload the class from the namespace `\OCA\\AppInfo\Application`, like `\OCA\MyApp\AppInfo\Application`, where _MyApp_ would be the name of your app. The file will therefore have the location `myapp/lib/AppInfo/Application.php`.
registerEventListener(
BeforeUserDeletedEvent::class,
UserDeletedListener::class
);
}
public function boot(IBootContext $context): void {
// ... boot logic goes here ...
/\*\* @var IManager $manager \*/
$manager \= $context\->getAppContainer()\->query(IManager::class);
$manager\->registerNotifierService(Notifier::class);
}
}
Note that the context objects of the methods `register` and `boot` have different interfaces and thus have different capabilities appropriate for their stage.
Bootstrapping process[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#bootstrapping-process "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------
To give a better overview of _when_ each of the bootstrapping stages are reached and how they app can interact with them, this section explains the changes done for Nextcloud 20.
### Nextcloud 20 and later[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#nextcloud-20-and-later "Link to this heading")
Nextcloud 20 is the first release with the interface `\OCP\AppFramework\Bootstrap\IBootstrap`. This interface can be implemented by your app’s `Application` class to signal that it wants to act on the bootstrapping stages. The major difference between this and the old process is that the bootstrapping is not performed in sequence, but apps register and boot interleaved. This should ensure that an app that `boot`s can rely on all other apps’ registration to be finished.
The overall process is as follows:
1. In each installed and enabled app that has an `Application` class that also implements `IBootstrap`, the `register` method will be called. This method receives a context argument via which the app can prime the dependency injection container and register other services lazily, e.g. by calling `$context->registerService(...)`. The emphasis is on **laziness**. At this very early stage of the process lifetime, no other apps nor all of the server components are ready. Therefore the app **must not** try to use anything except the API provided by the context. That shall ensure that all apps can safely run their registration logic before any services are queried (instantiated) from the DI container or related code is run.
2. Nextcloud will load groups of certain apps early, e.g. filesystem or session apps, and other later.
3. Nextcloud will query the app’s `Application` class (again), no matter whether it implements `IBootstrap` or not.
4. Nextcloud will invoke the [boot](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#app-bootstrap-boot)
method of every `Application` instance that implements `IBootstrap`. At this stage you may assume that all registrations via `IBootstrap::register` have completed.
#### Booting an app[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#booting-an-app "Link to this heading")
Any code that should run once for every Nextcloud process goes into the `boot` method of an app’s `Application` class. Use this mechanism carefully as it could have a negative effect on Nextcloud’s overall performance.
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#id3 "Link to this code")
getAppContainer()\->query(IFooManager::class); $manager\->registerCustomFoo(MyFooImpl::class); }
}
The code above fetches a fictional _foo manager_ to register an app class. The boot context object comes with a `injectFn` helper that eases dependency injection inside the `boot` method by injecting arguments of a callable:
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#id4 "Link to this code")
injectFn(function(IFooManager $manager) { $manager\->registerCustomFoo(MyFooImpl::class); }); }
}
With the help of `Closure::fromCallable` you can also delegate to other methods that get their arguments injected:
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#id5 "Link to this code")
injectFn($this\->registerFoo(...)); }
protected function registerFoo(IFooManager $manager): void { $manager\->registerCustomFoo(MyFooImpl::class); }
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Front-end — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/stable/developer_manual/basics/index.html)
* Front-end
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/front-end/index.rst)
* * *
Front-end[](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/index.html#front-end "Link to this heading")
=====================================================================================================================================
* [Templates](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/templates.html)
* [Including templates](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/templates.html#including-templates)
* [Including CSS and JavaScript](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/templates.html#including-css-and-javascript)
* [Including images](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/templates.html#including-images)
* [JavaScript](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/js.html)
* [Sending the CSRF token](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/js.html#sending-the-csrf-token)
* [Generating URLs](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/js.html#generating-urls)
* [Extending core parts](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/js.html#extending-core-parts)
* [Loading initial state](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/js.html#loading-initial-state)
* [Keyboard shortcuts](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/js.html#keyboard-shortcuts)
* [CSS](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/css.html)
* [Theming support](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/theming.html)
* [CSS variables](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/theming.html#css-variables)
* [JavaScript](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/theming.html#javascript)
* [Icons](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/theming.html#icons)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Controllers — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/31/developer_manual/basics/index.html)
* Controllers
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/controllers.rst)
* * *
Controllers[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#controllers "Link to this heading")
=================================================================================================================================
Controllers are used to connect [routes](https://docs.nextcloud.com/server/31/developer_manual/basics/routing.html)
with app logic. Think of it as callbacks that are executed once a request has come in. Controllers are defined inside the **lib/Controller/** directory.
To create a controller, simply extend the Controller class and create a method that should be executed on a request:
$id = 3
// $doMore = false
// $value = 3.5
}
}
The following types will be cast:
* **bool** or **boolean**
* **float**
* **int** or **integer**
### JSON parameters[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#json-parameters "Link to this heading")
It is possible to pass JSON using a POST, PUT or PATCH request. To do that the **Content-Type** header has to be set to **application/json**. The JSON is being parsed as an array and the first level keys will be used to pass in the arguments, e.g.:
POST /index.php/apps/myapp/authors
Content\-Type: application/json
{
"name": "test",
"number": 3,
"publisher": true,
"customFields": {
"mail": "test@example.com",
"address": "Somewhere"
}
}
"test@example.com", "address" => "Somewhere")
}
}
### Reading headers, files, cookies and environment variables[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#reading-headers-files-cookies-and-environment-variables "Link to this heading")
Headers, files, cookies and environment variables can be accessed directly from the request object:
request\->getHeader('Content-Type'); // $\_SERVER\['HTTP\_CONTENT\_TYPE'\]
$cookie \= $this\->request\->getCookie('myCookie'); // $\_COOKIES\['myCookie'\]
$file \= $this\->request\->getUploadedFile('myfile'); // $\_FILES\['myfile'\]
$env \= $this\->request\->getEnv('SOME\_VAR'); // $\_ENV\['SOME\_VAR'\]
}
}
Why should those values be accessed from the request object and not from the global array like $\_FILES? Simple: [because it’s bad practice](http://c2.com/cgi/wiki?GlobalVariablesAreBad)
and will make testing harder.
### Reading and writing session variables[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#reading-and-writing-session-variables "Link to this heading")
To set, get or modify session variables, the ISession object has to be injected into the controller.
Nextcloud will read existing session data at the beginning of the request lifecycle and close the session afterwards. This means that in order to write to the session, the session has to be opened first. This is done implicitly when calling the set method, but would close immediately afterwards. To prevent this, the session has to be explicitly opened by calling the reopen method.
Alternatively, you can use the `#[UseSession]` attribute to automatically open and close the session for you.
use OCP\\AppFramework\\Controller;
use OCP\\AppFramework\\Http\\Attribute\\UseSession;
use OCP\\AppFramework\\Http\\Response;
class PageController extends Controller {
#\[UseSession\] public function writeASessionVariable(): Response {
// ...
}
}
Note
The `#[UseSession]` was added in Nextcloud 26 and requires PHP 8.0 or later. If your app targets older releases and PHP 7.x then use the deprecated `@UseSession` annotation.
/\*\*
\* @UseSession \*/
public function writeASessionVariable(): Response {
// ....
}
In case the session may be read and written by concurrent requests of your application, keeping the session open during your controller method execution may be required to ensure that the session is locked and no other request can write to the session at the same time. When reopening the session, the session data will also get updated with the latest changes from other requests. Using the annotation will keep the session lock for the whole duration of the controller method execution.
For additional information on how session locking works in PHP see the article about [PHP Session Locking: How To Prevent Sessions Blocking in PHP requests](https://ma.ttias.be/php-session-locking-prevent-sessions-blocking-in-requests/)
.
Then session variables can be accessed like this:
Note
The session is closed automatically for writing, unless you add the `#[UseSession]` attribute!
session \= $session;
}
#\[UseSession\]
public function writeASessionVariable(): Response {
// read a session variable
$value \= $this\->session\['value'\];
// write a session variable
$this\->session\['value'\] \= 'new value';
}
}
### Setting cookies[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#setting-cookies "Link to this heading")
Cookies can be set or modified directly on the response class:
addCookie('foo', 'bar');
$response\->addCookie('bar', 'foo', new DateTime('2015-01-01 00:00'));
return $response;
}
/\*\*
\* Invalidates the cookie "foo"
\* Invalidates the cookie "bar" and "bazinga"
\*/
public function invalidateCookie(): TemplateResponse {
$response \= new TemplateResponse(...);
$response\->invalidateCookie('foo');
$response\->invalidateCookies(array('bar', 'bazinga'));
return $response;
}
}
Responses[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#responses "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------
Similar to how every controller receives a request object, every controller method has to return a Response. This can be in the form of a Response subclass or in the form of a value that can be handled by a registered responder.
### JSON[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#json "Link to this heading")
Returning JSON is simple, just pass an array to a JSONResponse:
'hi');
return new JSONResponse($params);
}
}
Because returning JSON is such a common task, there’s even a shorter way to do this:
'hi');
}
}
Why does this work? Because the dispatcher sees that the controller did not return a subclass of a Response and asks the controller to turn the value into a Response. That’s where responders come in.
### Responders[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#responders "Link to this heading")
Responders are short functions that take a value and return a response. They are used to return different kinds of responses based on a **format** parameter which is supplied by the client. Think of an API that is able to return both XML and JSON depending on if you call the URL with:
?format=xml
or:
?format=json
The appropriate responder is being chosen by the following criteria:
* First the dispatcher checks the Request if there is a **format** parameter, e.g.:
?format=xml
or:
/index.php/apps/myapp/authors.{format}
* If there is none, take the **Accept** header, use the first mimetype and cut off _application/_. In the following example the format would be _xml_:
Accept: application/xml, application/json
* If there is no Accept header or the responder does not exist, format defaults to **json**.
By default there is only a responder for JSON but more can be added easily:
registerResponder('xml', function($value) {
if ($value instanceof DataResponse) {
return new XMLResponse(
$value\->getData(),
$value\->getStatus(),
$value\->getHeaders()
);
} else {
return new XMLResponse($value);
}
});
return array('test' \=> 'hi');
}
}
Note
The above example would only return XML if the **format** parameter was _xml_. If you want to return an XMLResponse regardless of the format parameter, extend the Response class and return a new instance of it from the controller method instead.
Because returning values works fine in case of a success but not in case of failure that requires a custom HTTP error code, you can always wrap the value in a **DataResponse**. This works for both normal responses and error responses.
'not found!'), Http::STATUS\_NOT\_FOUND);
}
}
}
### Templates[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#templates "Link to this heading")
A [template](https://docs.nextcloud.com/server/31/developer_manual/basics/front-end/templates.html)
can be rendered by returning a TemplateResponse. A TemplateResponse takes the following parameters:
* **appName**: tells the template engine in which app the template should be located
* **templateName**: the name of the template inside the templates/ folder without the .php extension
* **parameters**: optional array parameters that are available in the template through $\_, e.g.:
array('key' \=> 'something')
can be accessed through:
$\_\['key'\]
* **renderAs**: defaults to _user_, tells Nextcloud if it should include it in the web interface, or in case _blank_ is passed solely render the template
'hi');
return new TemplateResponse($this\->appName, $templateName, $parameters);
}
}
### Public page templates[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#public-page-templates "Link to this heading")
For public pages, that are rendered to users who are not logged in to the Nextcloud instance, a `OCP\\AppFramework\\Http\\Template\\PublicTemplateResponse` should be used, to load the correct base template. It also allows adding an optional set of actions that will be shown in the top right corner of the public page.
appName, 'main', \[\]);
$template\->setHeaderTitle('Public page');
$template\->setHeaderDetails('some details');
$template\->setHeaderActions(\[\
new SimpleMenuAction('download', 'Label 1', 'icon-css-class1', 'link-url', 0),\
new SimpleMenuAction('share', 'Label 2', 'icon-css-class2', 'link-url', 10),\
\]);
return $template;
}
}
The header title and subtitle will be rendered in the header, next to the logo. The action with the highest priority (lowest number) will be used as the primary action, others will shown in the popover menu on demand.
A `OCP\\AppFramework\\Http\\Template\\SimpleMenuAction` will be a link with an icon added to the menu. App developers can implement their own types of menu renderings by adding a custom class implementing the `OCP\\AppFramework\\Http\\Template\\IMenuAction` interface.
### Redirects[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#redirects "Link to this heading")
A redirect can be achieved by returning a RedirectResponse:
addHeader('Content-Type', 'application/xml');
$this\->xml \= $xml;
}
public function render(): string {
$root \= new SimpleXMLElement('');
array\_walk\_recursive($this\->xml, array ($root, 'addChild'));
return $xml\->asXML();
}
}
### Streamed and lazily rendered responses[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#streamed-and-lazily-rendered-responses "Link to this heading")
By default all responses are rendered at once and sent as a string through middleware. In certain cases this is not a desirable behavior, for instance if you want to stream a file in order to save memory. To do that use the now available **OCP\\AppFramework\\Http\\StreamResponse** class:
` tag, see ‘script-src-elem’ **(enabled by default)**
Note
`useStrictDynamicOnScripts` is enabled by default to allow module javascript to load its dependencies using `import` since Nextcloud 28. You can disable this by passing **false** as the parameter.
The following methods whitelist domains by passing in a domain or \* for any domain:
* **addAllowedScriptDomain** (string $domain)
* **addAllowedStyleDomain** (string $domain)
* **addAllowedFontDomain** (string $domain)
* **addAllowedImageDomain** (string $domain)
* **addAllowedConnectDomain** (string $domain)
* **addAllowedMediaDomain** (string $domain)
* **addAllowedObjectDomain** (string $domain)
* **addAllowedFrameDomain** (string $domain)
* **addAllowedChildSrcDomain** (string $domain)
The following policy for instance allows images, audio and videos from other domains:
addAllowedImageDomain('\*');
\->addAllowedMediaDomain('\*');
$response\->setContentSecurityPolicy($csp);
}
}
### OCS[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#ocs "Link to this heading")
Note
This is purely for compatibility reasons. If you are planning to offer an external API, go for a [REST APIs](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/rest_apis.html)
instead.
In order to ease migration from OCS API routes to the App Framework, an additional controller and response have been added. To migrate your API you can use the **OCP\\AppFramework\\OCSController** base class and return your data in the form of a DataResponse in the following way:
\[\
\[\
'name' \=> 'Share#getShares',\
'url' \=> '/api/v1/shares',\
'verb' \=> 'GET',\
\],\
\],\
\];
Now your method will be reachable via `/ocs/v2.php/apps//api/v1/shares`
### Handling errors[](https://docs.nextcloud.com/server/31/developer_manual/basics/controllers.html#handling-errors "Link to this heading")
Sometimes a request should fail, for instance if an author with id 1 is requested but does not exist. In that case use an appropriate [HTTP error code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error)
to signal the client that an error occurred.
Each response subclass has access to the **setStatus** method which lets you set an HTTP status code. To return a JSONResponse signaling that the author with id 1 has not been found, use the following code:
index() method should not check the CSRF token because it has not yet been sent to the client and because of that can’t work.
To turn off checks the following _Attributes_ can be added before the controller:
* `#[NoAdminRequired]`: Also users that are not admins can access the page
* `#[PublicPage]`: Everyone can access the page without having to log in
* `#[NoTwoFactorRequired]`: A user can access the page before the two-factor challenge has been passed (use this wisely and only in two-factor auth apps, e.g. to allow setup during login)
* `#[NoCSRFRequired]`: Don’t check the CSRF token (use this wisely since you might create a security hole; to understand what it does see [CSRF in the security section](https://docs.nextcloud.com/server/31/developer_manual/prologue/security.html#cross-site-request-forgery)
)
Note
The attributes are only available in Nextcloud 27 or later. In older versions annotations with the same names exist:
* `@NoAdminRequired` instead of `#[NoAdminRequired]`
* `` @PublicPage` `` instead of `#[PublicPage]`
* `` @NoTwoFactorRequired` `` instead of `#[NoTwoFactorRequired]`
* `` @NoCSRFRequired` `` instead of `#[NoCSRFRequired]`
A controller method that turns off all checks would look like this:
auth->isSuccessful here is just an
// example.
if (!$this\->auth\->isSuccessful()) {
$templateResponse\->throttle(); }
return $templateResponse;
}
}
A controller can also have multiple factors to brute force against. In this case you can specify multiple attributes and then in the throttle you specify the action which was violated. This is especially useful when a secret, in the sample below token, could be guessed on multiple endpoints e.g. a share token on the API level, preview endpoint, frontend controller, etc. while another secret (password), is specific to this one controller method.
shareManager\->getByToken($token)) {
$templateResponse\->throttle(\['action' \=> 'token'\]); }
// …
if (!$share\->verifyPassword($password)) {
$templateResponse\->throttle(\['action' \=> 'password'\]); }
return $templateResponse;
}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Tutorial — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html)
* Tutorial
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/tutorial.rst)
* * *
Tutorial[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/tutorial.html#tutorial "Link to this heading")
=====================================================================================================================================
To help you get started on Nextcloud app development we have compiled a comprehensive set of tutorials that cover everything from setting up your development environment to developing a full fledged app with database storage.
Please head [here](https://cloud.nextcloud.com/s/iyNGp8ryWxc7Efa?path=%2F)
to get started.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Front-end code — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* Front-end code
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/code-front-end.rst)
* * *
Front-end code[](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html#front-end-code "Link to this heading")
==========================================================================================================================================
Building Vue components and scripts[](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html#building-vue-components-and-scripts "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
We are moving more and more toward using Vue.js in the front-end, starting with Settings. For building the code on changes, use these terminal commands in the root folder:
\# install dependencies
npm install
\# build for development
npm run dev
\# build for development and watch edits
npm run watch
\# build for production with minification
npm run build
Building styles[](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html#building-styles "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------
Styles are written in SCSS and compiled to css.
\# install dependencies
make dev-setup
\# compile style sheets
npm run sass
\# compile style sheets and watch edits
npm run sass:watch
Committing changes[](https://docs.nextcloud.com/server/31/developer_manual/server/code-front-end.html#committing-changes "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
**When making changes, also commit the compiled files!**
We still use Handlebars templates in some places in Files and Settings. We will replace these step-by-step with Vue.js, but in the meantime, you need to compile them separately.
If you don’t have Handlebars installed yet, you can do it with this terminal command:
sudo npm install -g handlebars
Then inside the root folder of your local Nextcloud development installation, run this command in the terminal every time you changed a `.handlebars` file to compile it:
./build/compile-handlebars-templates.sh
Before checking in JS changes, make sure to also build for production:
make build-js-production
Then add the compiled files for committing.
To save some time, to only rebuild for a specific app, use the following and replace the module with the app name:
MODULE=user\_status make build-js-production
Please note that if you used `make build-js` or `make watch-js` before, you’ll notice that a lot of files were marked as changed, so might need to clear the workspace first.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Nextcloud Assistant — Nextcloud latest Administration Manual latest documentation
* [](https://docs.nextcloud.com/server/latest/admin_manual/contents.html)
* [Artificial Intelligence](https://docs.nextcloud.com/server/latest/admin_manual/ai/index.html)
* Nextcloud Assistant
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/admin_manual/ai/app_assistant.rst)
* * *
Nextcloud Assistant[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#nextcloud-assistant "Link to this heading")
===============================================================================================================================================
Nextcloud assistant is the primary graphical user interface for interacting with artificial intelligence features in Nextcloud.
It offers the graphical user interface for the unified AI Task processing API offering features like summarizing text, generating headlines, asking arbitrary questions, transcription of media files, image generation and it integrates with the context\_chat app to offer in-context answers about your own data stored in Nextcloud. The assistant app also offers a chat interface to interact with the chosen language model. Nextcloud can provide customer support upon request, please talk to your account manager for the possibilities.
Find the user documentation here: [https://github.com/nextcloud/assistant/tree/main/docs/user](https://github.com/nextcloud/assistant/tree/main/docs/user)
Installation[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#installation "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------
You can install the _assistant_ app via the “Apps” page in Nextcloud, or by executing
sudo \-E \-u www\-data php occ app:enable assistant
App store[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#app-store "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------
You can also find the app in our app store, where you can write a review: [https://apps.nextcloud.com/apps/assistant](https://apps.nextcloud.com/apps/assistant)
Repository[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#repository "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------
You can find the app’s code repository on GitHub where you can report bugs and contribute fixes and features: [https://github.com/nextcloud/assistant](https://github.com/nextcloud/assistant)
Nextcloud customers should file bugs directly with our Customer Support.
Related apps[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#related-apps "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------
Artificial intelligence at Nextcloud is built in a modular way, allowing you to choose from a variety of solutions for your needs. In order to make use of the various features of the Assistant you will need additional apps that act as backends to provide the actual implementation of the AI functionality. In the Nextcloud administration settings under “Artificial intelligence” you can select which AI backend app to use for which tasks. Note that some of the backend apps are only community maintained, while others are available for Customer support upon request.
The AI admin settings will show all types of Assistant Tasks that are implemented by all your installed apps. Task types can be disabled in the AI admin settings so they are not available for the Assistant or other apps even if they are implemented. All implemented Task types are enabled by default.
**Note**: At Nextcloud we focus on creating on-premise AI apps that run fully self-hosted on your own servers in order to preserve your privacy and data sovereignty. However, you can also offload these resource-heavy tasks to an [“AI as a Service” provider](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
.
**Note**: When using our on-premise AI apps, make sure you have a GPU with enough VRAM that fits all the features you need. For each app documented here you will find its hardware requirements.
### Machine translation[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#machine-translation "Link to this heading")
In order to make use of machine translation features in the assistant, you will need an app that provides a translation backend: \* [translate2 (ExApp)](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_translate2.html#ai-app-translate2)
- Runs open source AI translation models locally on your own server hardware (Customer support available upon request) \* _integration\_deepl_ - Integrates with the deepl API to provide translation functionality from Deepl.com servers (Only community supported)
### Speech-To-Text[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#speech-to-text "Link to this heading")
In order to make use of Speech-to-Text, you will need an app that provides a Speech-To-Text backend:
* [stt\_whisper2](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_stt_whisper2.html#ai-app-stt-whisper2)
- Runs open source AI Speech-To-Text models on your own server hardware (Customer support available upon request)
* [OpenAI and LocalAI integration (via OpenAI API)](https://apps.nextcloud.com/apps/integration_openai)
- Integrates with the OpenAI API to provide AI functionality from OpenAI servers (Customer support available upon request; see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
### Text processing[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#text-processing "Link to this heading")
In order to make use of text processing features in the assistant, you will need an app that provides a Text processing backend:
* [llm2](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_llm2.html#ai-app-llm2)
- Runs open source AI language models locally on your own server hardware (Customer support available upon request)
* * [OpenAI and LocalAI integration (via OpenAI API)](https://apps.nextcloud.com/apps/integration_openai)
- Integrates with the OpenAI API to provide AI functionality from OpenAI servers (Customer support available upon request; see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
* _integration\_watsonx_ - Integrates with the IBM watsonx.ai API to provide AI functionality from IBM Cloud servers (Customer support available upon request; see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
These apps currently implement the following Assistant Tasks:
* _Generate text_ (Tested with OpenAI GPT-3.5 and Llama 3.1 8B)
* _Summarize_ (Tested with OpenAI GPT-3.5 and Llama 3.1 8B)
* _Generate headline_ (Tested with OpenAI GPT-3.5 and Llama 3.1 8B)
* _Extract topics_ (Tested with OpenAI GPT-3.5 and Llama 3.1 8B)
* _Context write_ (Tested with OpenAI GPT-3.5 and Llama 3.1 8B)
* _Reformulate text_ (Tested with OpenAI GPT-3.5 and Llama 3.1 8B)
These tasks may work with other models, but we can give no guarantees.
### Text-To-Image[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#text-to-image "Link to this heading")
In order to make use of Text-To-Image features, you will need an app that provides an image generation backend:
* [tex2image\_stablediffusion2](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_text2image_stablediffusion2.html#ai-app-text2image-stablediffusion2)
(Customer support available upon request)
* * [OpenAI and LocalAI integration (via OpenAI API)](https://apps.nextcloud.com/apps/integration_openai)
- Integrates with the OpenAI API to provide AI functionality from OpenAI servers (Customer support available upon request; see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
* _integration\_replicate_ - Integrates with the replicate API to provide AI functionality from replicate servers (see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
### Context Chat[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#context-chat "Link to this heading")
In order to make use of our special Context Chat feature, offering insights about your own documents and data stored in Nextcloud, you will need the following apps:
* [context\_chat + context\_chat\_backend](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_context_chat.html#ai-app-context-chat)
- (Customer support available upon request)
You will also need a text processing provider as specified above (ie. llm2, integration\_openai or integration\_watsonx).
### Chat[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#chat "Link to this heading")
In order to make use of our “Chat with AI” feature you will need any one of the following apps:
* [llm2](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_llm2.html#ai-app-llm2)
- Runs open source AI language models locally on your own server hardware (Customer support available upon request)
* * [OpenAI and LocalAI integration (via OpenAI API)](https://apps.nextcloud.com/apps/integration_openai)
- Integrates with the OpenAI API to provide AI functionality from OpenAI servers (Customer support available upon request; see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
### Voice Chat[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#voice-chat "Link to this heading")
In order to make use of our “Audio chat” feature which allows you to interact with the assistant Chat via your Voice and Ears as if in a real conversation, you will need any of the following set of apps:
* Either
* [OpenAI and LocalAI integration (via OpenAI API)](https://apps.nextcloud.com/apps/integration_openai)
- Integrates with the OpenAI API to provide AI functionality from OpenAI servers (Customer support available upon request; see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
* Or
* [llm2](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_llm2.html#ai-app-llm2)
- Runs open source AI language models locally on your own server hardware (Customer support available upon request)
* [stt\_whisper2](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_stt_whisper2.html#ai-app-stt-whisper2)
- Runs open source AI Speech-To-Text models on your own server hardware (Customer support available upon request)
* [text2speech\_kokoro](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_text2speech_kokoro.html#ai-app-text2speech-kokoro)
- Runs open source AI Text-To-Speech models on your own server hardware (Customer support available upon request)
### Context Agent[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#context-agent "Link to this heading")
In order to make use of our AI agent feature, offering the execution of actions on behalf of the user based on the AI chat, you will need the following apps:
* [context\_agent](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_context_agent.html#ai-app-context-agent)
- (Customer support available upon request)
You will also need a text processing provider as specified above (ie. _llm2_ or _integration\_openai_).
### Text-To-Speech[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#text-to-speech "Link to this heading")
In order to make use of Text-To-Speech, you will need an app that provides a Text-To-Speech backend, which is one of the following:
* [OpenAI and LocalAI integration (via OpenAI API)](https://apps.nextcloud.com/apps/integration_openai)
- Integrates with the OpenAI API to provide AI functionality from OpenAI servers (Customer support available upon request; see [AI as a Service](https://docs.nextcloud.com/server/latest/admin_manual/ai/ai_as_a_service.html#ai-ai-as-a-service)
)
* [text2speech\_kokoro](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_text2speech_kokoro.html#ai-app-text2speech-kokoro)
- Runs open source AI Text-To-Speech models on your own server hardware (Customer support available upon request)
Configuration[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#configuration "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------
The Assistant admin settings can be found under the “Artificial intelligence” section. You can disable the assistant top menu entry there. You can also disable the AI-related smart pickers. The occ commands to change the options are listed below.
### Assistant configuration[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#assistant-configuration "Link to this heading")
1. Top-right Assistant
occ config:app:set assistant assistant\_enabled \--value\=1 \--type\=string
To enable/disable the assistant button from the top-right corner for all the users.
2. AI text generation smart picker
occ config:app:set assistant free\_prompt\_picker\_enabled \--value\=1 \--type\=string
To enable/disable the AI text generation smart picker for all the users.
3. Text-to-image smart picker
occ config:app:set assistant text\_to\_image\_picker\_enabled \--value\=1 \--type\=string
To enable/disable the text-to-image smart picker for all the users.
4. Speech-to-text smart picker
occ config:app:set assistant speech\_to\_text\_picker\_enabled \--value\=1 \--type\=string
To enable/disable the speech-to-text smart picker for all the users.
### Task processing[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#task-processing "Link to this heading")
1. List Tasks
occ taskprocessing:task:list
lists all task processing tasks.
2. Get Task
occ taskprocessing:task:get $TASK\_ID
shows all information for a specific task.
3. Enable or disable a Task type
occ taskprocessing:task-type:set-enabled $TASK\_TYPE\_ID 1
Set 1 to enable and 0 to disable an implemented task type.
4. Get Task statistics
occ taskprocessing:task:stats
shows statistics for all task processing Tasks.
5. Clean-up old tasks
occ taskprocessing:task:cleanup
delete tasks that are older than this number of seconds, defaults to 4 months.
### Image storage[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#image-storage "Link to this heading")
Days until generated images are deleted if they are not viewed.
occ config:app:set assistant max\_image\_generation\_idle\_time \--value\=90 \--type\=integer
### Chat with AI[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#chat-with-ai "Link to this heading")
1. Chat User Instructions for Chat Completions
occ config:app:set assistant chat\_user\_instructions \--value\="hello world"
The user instructions that are prepended before the chat messages for the AI model to understand the context of the block of text. This is a good place not only to instruct the AI model to be polite and kind but also to for example answer all the queries in a particular language or better yet, follow the user’s language. The sky is the limit.
**Note**: The default instructions are optimized to work well across a variety of language models, but may not be optimal for the specific model you choose. Specifically, the model may be tempted to mention the user’s name a bit too often and may mention the user’s language in an unusual manner.
2. Chat User Instructions for Title Generation
occ config:app:set assistant chat\_user\_instructions\_title \--value\="hello title"
This field is appended to the block of chat messages, i.e. attached after the messages. It is done this way to allow it to be used even with text completion models which could have the instructions as “The title for the above conversation could be "”.
3. Last N messages to consider for chat completions
occ config:app:set assistant chat\_last\_n\_messages \--value\=10
The number of latest messages to consider for generating the next message. This does not include the user instructions, which is always considered in addition to this. This value should be adjusted in case you are hitting the token limit in your conversations too often. The AI text generation provider should ideally handle the max token limit case.
### Improve AI task pickup speed[](https://docs.nextcloud.com/server/latest/admin_manual/ai/app_assistant.html#improve-ai-task-pickup-speed "Link to this heading")
See [the relevant section in AI Overview](https://docs.nextcloud.com/server/latest/admin_manual/ai/overview.html#ai-overview-improve-ai-task-pickup-speed)
for more information.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/admin_manual)
[stable](https://docs.nextcloud.com/server/stable/admin_manual)
[32](https://docs.nextcloud.com/server/32/admin_manual)
[31](https://docs.nextcloud.com/server/31/admin_manual)
---
# Request lifecycle — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/stable/developer_manual/basics/index.html)
* Request lifecycle
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/request_lifecycle.rst)
* * *
Request lifecycle[](https://docs.nextcloud.com/server/stable/developer_manual/basics/request_lifecycle.html#request-lifecycle "Link to this heading")
=======================================================================================================================================================
A typical HTTP request consists of the following:
* **A URL**: e.g. /index.php/apps/myapp/something
* **Request Parameters**: e.g. ?something=true&name=tom
* **A Method**: e.g. GET
* **Request headers**: e.g. Accept: application/json
The following sections will present an overview over how that request is being processed to provide an in depth view over how Nextcloud works. If you are not interested in the internals or don’t want to execute anything before and after your controller, feel free to skip this section and continue directly with defining [your app’s routes](https://docs.nextcloud.com/server/stable/developer_manual/basics/routing.html)
.
Front controller[](https://docs.nextcloud.com/server/stable/developer_manual/basics/request_lifecycle.html#front-controller "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------
In the beginning, all requests are sent to Nextcloud’s `index.php` which in turn executes `lib/base.php`. This file inspects the HTTP headers, abstracts away differences between different Web servers and initializes the basic classes. Afterwards the basic apps are being loaded in the following order:
* Authentication backends
* Filesystem
* Logging
The type of the app is determined by inspecting the app’s [configuration file](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html)
(`appinfo/info.xml`). Each installed app is being loaded and executed (see [Bootstrap](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html)
). That means that if you want to execute code before a specific app is being run, you can place code in your app’s [Navigation and pre-app configuration](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html)
file.
Afterwards the following steps are performed:
* Try to authenticate the user
* Load and execute all the remaining apps’ [Navigation and pre-app configuration](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html)
files
* Load and run all the routes in the apps’ `appinfo/routes.php`
* Execute the router
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Request lifecycle — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/32/developer_manual/basics/index.html)
* Request lifecycle
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/request_lifecycle.rst)
* * *
Request lifecycle[](https://docs.nextcloud.com/server/32/developer_manual/basics/request_lifecycle.html#request-lifecycle "Link to this heading")
===================================================================================================================================================
A typical HTTP request consists of the following:
* **A URL**: e.g. /index.php/apps/myapp/something
* **Request Parameters**: e.g. ?something=true&name=tom
* **A Method**: e.g. GET
* **Request headers**: e.g. Accept: application/json
The following sections will present an overview over how that request is being processed to provide an in depth view over how Nextcloud works. If you are not interested in the internals or don’t want to execute anything before and after your controller, feel free to skip this section and continue directly with defining [your app’s routes](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html)
.
Front controller[](https://docs.nextcloud.com/server/32/developer_manual/basics/request_lifecycle.html#front-controller "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------
In the beginning, all requests are sent to Nextcloud’s `index.php` which in turn executes `lib/base.php`. This file inspects the HTTP headers, abstracts away differences between different Web servers and initializes the basic classes. Afterwards the basic apps are being loaded in the following order:
* Authentication backends
* Filesystem
* Logging
The type of the app is determined by inspecting the app’s [configuration file](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html)
(`appinfo/info.xml`). Each installed app is being loaded and executed (see [Bootstrap](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html)
). That means that if you want to execute code before a specific app is being run, you can place code in your app’s [Navigation and pre-app configuration](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html)
file.
Afterwards the following steps are performed:
* Try to authenticate the user
* Load and execute all the remaining apps’ [Navigation and pre-app configuration](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html)
files
* Load and run all the routes in the apps’ `appinfo/routes.php`
* Execute the router
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Middlewares — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/32/developer_manual/basics/index.html)
* Middlewares
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/middlewares.rst)
* * *
Middlewares[](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#middlewares "Link to this heading")
=================================================================================================================================
Middleware is logic that is run before and after each request and is modeled after [Django’s Middleware system](https://docs.djangoproject.com/en/dev/topics/http/middleware/)
. It offers the following hooks:
* `beforeController`: This is executed before a controller method is being executed. This allows you to plug additional checks or logic before that method, like for instance security checks
* `afterException`: This is being run when either the beforeController method or the controller method itself is throwing an exception. The middleware is asked in reverse order to handle the exception and to return a response. If the middleware can’t handle the exception, it throws the exception again
* `afterController`: This is being run after a successful controller method call and allows the manipulation of a Response object. The middleware is run in reverse order
* `beforeOutput`: This is being run after the response object has been rendered and allows the manipulation of the outputted text. The middleware is run in reverse order

To generate your own middleware, simply inherit from the Middleware class and overwrite the methods that should be used.
registerMiddleware(CensorMiddleware::class); }
public function boot(IBootContext $context): void {}
}
Global Middlewares[](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#global-middlewares "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
Added in version 26.
Registered middleware will only intercept requests of the same app by default. To make a middleware _global_ and trigger for other apps’ middleware, add true as the second argument of the `registerMiddleware` call:
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#id3 "Link to this code")
registerMiddleware(MonitoringMiddleware::class, true); }
public function boot(IBootContext $context): void {}
}
Dependency Injection Container Registration[](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#dependency-injection-container-registration "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Deprecated since version 20.
Middleware can also be added using the **registerMiddleware** method of the container:
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#id4 "Link to this code")
getContainer();
// executed in the order that it is registered $container\->registerMiddleware(CensorMiddleware::class); }
}
Note
The order is important! The middleware that is registered first gets run first in the **beforeController** method. For all other hooks, the order is being reversed, meaning: if a middleware is registered first, it gets run last.
Parsing annotations[](https://docs.nextcloud.com/server/32/developer_manual/basics/middlewares.html#parsing-annotations "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------
Sometimes it is useful to conditionally execute code before or after a controller method. This can be done by defining custom annotations. An example would be to add a custom authentication method or simply add an additional header to the response. To access the parsed annotations, inject the **ControllerMethodReflector** class:
reflector \= $reflector;
}
/\*\*
\* Add custom header if @MyHeader is used
\*/
public function afterController($controller, $methodName, Response $response): Response {
if($this\->reflector\->hasAnnotation('MyHeader')) {
$response\->addHeader('My-Header', 3);
}
return $response;
}
}
Note
An annotation always starts with an uppercase letter
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Caching — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/31/developer_manual/basics/index.html)
* Caching
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/caching.rst)
* * *
Caching[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#caching "Link to this heading")
=====================================================================================================================
Results of expensive or slow operations can be cached to speed up Nextcloud and its apps.
Types of caches[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#types-of-caches "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------
Nextcloud offers in-memory, local and distributed caches. The caching back-end (APCu, Redis, Memcached) is configurable.
For single server setups, admins typically only configure one type of cache. Larger installations can have two types of cache. The Nextcloud API lets you pick a cache type. The following table tries to highlight the main advantages and disadvantages of each type.
| | In-memory cache | Local cache | Distributed cache |
| --- | --- | --- | --- |
| **Latency** | Low | Low | High |
| **Data scope** | Same process | Application server | Full cluster |
| **Expiration** | End of process | TTL reached | TTL reached |
For scalability it should be preferred to use local caches. A local cache has to be populated on each application server, but avoids creating a bottleneck of too much traffic on the distributed cache. A distributed cache is most useful for data that _has to be synchronized_ across the full Nextcloud cluster.
In-memory cache[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#in-memory-cache "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------
The `OCP\Cache\CappedMemoryCache` class is an in-memory cache that can be used like an array:
lib/Service/PictureService.php[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#id1 "Link to this code")
cache \= new CappedMemoryCache(64); }
public function getPicture(string $url): void {
if (isset($this\->cache\[$url\])) { return $this\->cache\[$url\]; }
// Fetch picture and serialize result into $picture
$this\->cache\[$url\] \= $picture; return $picture;
}
}
A cache instance can also be built by the cache factory. This approach allows mocking the injected factory for finer control during [unit testing](https://docs.nextcloud.com/server/31/developer_manual/basics/testing.html#testing-php)
:
lib/Service/PictureService.php[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#id2 "Link to this code")
cacheFactory \= $cacheFactory;
}
public function getPicture(string $url): void {
// Initialize the cache. The instance has to be remembered because // each call to \`createInMemory\` returns a fresh, empty cache. if ($this\->cache \=== null) { $this\->cache \= $this\->cacheFactory\->createInMemory(64); }
if (isset($this\->cache\[$url\])) {
return $this\->cache\[$url\];
}
// Fetch picture and serialize result into $picture
$this\->cache\[$url\] \= $picture;
return $picture;
}
}
Local cache[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#local-cache "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------
A local cache instance can be acquired through the `\OCP\ICacheFactory` service. The factory can be injected:
lib/Service/PictureService.php[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#id3 "Link to this code")
cacheFactory \= $cacheFactory;
}
public function getPicture(string $url): void {
$cache \= $this\->cacheFactory\->createLocal('my-app-pictures'); $cachedPicture \= $cache\->get($url); if ($cachedPicture !== null) {
return $cachedPicture;
}
// Fetch picture and serialize result into $picture
$cache\->set($url, $picture, 6 \* 3600); // Cache result for 6h return $picture;
}
}
Distributed cache[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#distributed-cache "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------
A distributed cache instance can be acquired through the `\OCP\ICacheFactory` service. The factory can be injected:
lib/Service/PictureService.php[](https://docs.nextcloud.com/server/31/developer_manual/basics/caching.html#id4 "Link to this code")
cacheFactory \= $cacheFactory;
}
public function getPicture(string $url): void {
$cache \= $this\->cacheFactory\->createDistributed('my-app-pictures'); $cachedPicture \= $cache\->get($url); if ($cachedPicture !== null) {
return $cachedPicture;
}
// Fetch picture and serialize result into $picture
$cache\->set($url, $picture, 6 \* 3600); // Cache result for 6h return $picture;
}
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Introduction — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html)
* Introduction
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/intro.rst)
* * *
Introduction[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#introduction "Link to this heading")
==========================================================================================================================================
Create an app[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#create-an-app "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------
After [you’ve set up the development environment](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/devenv.html)
change into the Nextcloud apps directory:
cd /var/www/nextcloud/apps
Then create a skeleton app in the [app store](https://apps.nextcloud.com/developer/apps/generate)
. This doesn’t publish anything on the appstore yet, it just gives you a download.
Edit an existing app[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#edit-an-existing-app "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------
Alternatively, if you would like to contribute to an existing app instead of creating a new one, first [set up the development environment](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/devenv.html)
, then create an apps-extra folder in the Nextcloud root directory:
cd /var/www/nextcloud/apps\-extra
You can then configure Nextcloud to run apps from this directory, by changing your app\_paths system config in your config.php
'apps\_paths' \=> array (
0 \=> array (
'path' \=> '/var/www/html/apps',
'url' \=> '/apps',
'writable' \=> false,
),
1 \=> array (
'path' \=> '/var/www/html/apps-extra',
'url' \=> '/apps-extra',
'writable' \=> false,
),
),
Finally, clone the app to which you would like to contribute inside the apps-extra folder. For example:
> git clone [https://github.com/nextcloud/cookbook.git](https://github.com/nextcloud/cookbook.git)
Enable the app[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#enable-the-app "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------
The app can now be enabled on the Nextcloud apps page.
App architecture[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/intro.html#app-architecture "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
The following directories have now been created:
* **appinfo/**: Contains app metadata and configuration
* **css/**: Contains the CSS
* **img/**: Contains icons and images
* **js/**: Contains the JavaScript files
* **lib/**: Contains the PHP class files of your app
* **src/**: Contains the source code of your vue.js app
* **templates/**: Contains the templates
* **tests/**: Contains the tests
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Bootstrapping — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/32/developer_manual/app_development/index.html)
* Bootstrapping
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/bootstrap.rst)
* * *
Bootstrapping[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#bootstrapping "Link to this heading")
============================================================================================================================================
Every php process has a relatively short lifespan that lasts as long as the HTTP request or the invocation of the command line program. At the beginning of this lifespan, Nextcloud initializes its services. At the same time, any additional apps might want to register their services to Nextcloud as well. This event is called the _bootstrapping_ and this chapter shall shed some light on how to hook into this with an app.
The Application class[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#the-application-class "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
The Application class is the main entry point of an app. This class is optional but highly recommended if your app needs to register any services or run some code for every request.
Nextcloud will try to autoload the class from the namespace `\OCA\\AppInfo\Application`, like `\OCA\MyApp\AppInfo\Application`, where _MyApp_ would be the name of your app. The file will therefore have the location `myapp/lib/AppInfo/Application.php`.
registerEventListener(
BeforeUserDeletedEvent::class,
UserDeletedListener::class
);
}
public function boot(IBootContext $context): void {
// ... boot logic goes here ...
/\*\* @var IManager $manager \*/
$manager \= $context\->getAppContainer()\->query(IManager::class);
$manager\->registerNotifierService(Notifier::class);
}
}
Note that the context objects of the methods `register` and `boot` have different interfaces and thus have different capabilities appropriate for their stage.
Bootstrapping process[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#bootstrapping-process "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
To give a better overview of _when_ each of the bootstrapping stages are reached and how they app can interact with them, this section explains the changes done for Nextcloud 20.
### Nextcloud 20 and later[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#nextcloud-20-and-later "Link to this heading")
Nextcloud 20 is the first release with the interface `\OCP\AppFramework\Bootstrap\IBootstrap`. This interface can be implemented by your app’s `Application` class to signal that it wants to act on the bootstrapping stages. The major difference between this and the old process is that the bootstrapping is not performed in sequence, but apps register and boot interleaved. This should ensure that an app that `boot`s can rely on all other apps’ registration to be finished.
The overall process is as follows:
1. In each installed and enabled app that has an `Application` class that also implements `IBootstrap`, the `register` method will be called. This method receives a context argument via which the app can prime the dependency injection container and register other services lazily, e.g. by calling `$context->registerService(...)`. The emphasis is on **laziness**. At this very early stage of the process lifetime, no other apps nor all of the server components are ready. Therefore the app **must not** try to use anything except the API provided by the context. That shall ensure that all apps can safely run their registration logic before any services are queried (instantiated) from the DI container or related code is run.
2. Nextcloud will load groups of certain apps early, e.g. filesystem or session apps, and other later.
3. Nextcloud will query the app’s `Application` class (again), no matter whether it implements `IBootstrap` or not.
4. Nextcloud will invoke the [boot](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#app-bootstrap-boot)
method of every `Application` instance that implements `IBootstrap`. At this stage you may assume that all registrations via `IBootstrap::register` have completed.
#### Booting an app[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#booting-an-app "Link to this heading")
Any code that should run once for every Nextcloud process goes into the `boot` method of an app’s `Application` class. Use this mechanism carefully as it could have a negative effect on Nextcloud’s overall performance.
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#id3 "Link to this code")
getAppContainer()\->query(IFooManager::class); $manager\->registerCustomFoo(MyFooImpl::class); }
}
The code above fetches a fictional _foo manager_ to register an app class. The boot context object comes with a `injectFn` helper that eases dependency injection inside the `boot` method by injecting arguments of a callable:
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#id4 "Link to this code")
injectFn(function(IFooManager $manager) { $manager\->registerCustomFoo(MyFooImpl::class); }); }
}
With the help of `Closure::fromCallable` you can also delegate to other methods that get their arguments injected:
lib/AppInfo/Application.php[](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#id5 "Link to this code")
injectFn($this\->registerFoo(...)); }
protected function registerFoo(IFooManager $manager): void { $manager\->registerCustomFoo(MyFooImpl::class); }
}
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Setting up dev environment — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [ExApp development](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/index.html)
* Setting up dev environment
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/DevSetup.rst)
* * *
Setting up dev environment[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#setting-up-dev-environment "Link to this heading")
===========================================================================================================================================================================
AppAPI development requires a Nextcloud development environment setup. We highly recommend using [Julius Knorr’s Docker setup](https://github.com/juliusknorr/nextcloud-docker-dev)
for this. For an alternate environment without using Docker, please refer to the setup instructions in [Getting started](https://docs.nextcloud.com/server/stable/developer_manual/getting_started/devenv.html)
.
Suggested IDE: **PhpStorm**, though you can certainly use any IDE of your preference such as **VS Code** or **Vim**.
Install AppAPI[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#install-appapi "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------
All ExApps require the [AppAPI](https://apps.nextcloud.com/apps/app_api)
Nextcloud app as a dependency. As of Nextcloud version 30.0.1, AppAPI is automatically installed by default. If you prefer, you can also build the latest development version of AppAPI from the source code, in which case uninstall the release version of AppAPI and perform the following steps.
Clone the latest main branch:
> git clone https://github.com/nextcloud/app\_api.git && cd app\_api
or clone a specific version by specifying the version tag:
> git clone https://github.com/nextcloud/app\_api.git \--branch && cd app\_api
where `` is the version you want to install.
Then, build frontend assets in development mode:
> npm ci && npm run dev
Enable AppAPI from the directory where the `occ` command resides:
> ./occ app:enable \--force app\_api
### Deploy daemons types[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#deploy-daemons-types "Link to this heading")
There are two types of Deploy daemons that can be used for development and testing of ExApps:
1. `manual_install`: This type of Deploy daemon is running manually in the host machine. This is useful for ExApp development as you can run your ExApp directly on the host.
2. `docker_install`: This type of Deploy daemon is running in a Docker container.
You can register (create) these daemons in the AppAPI admin settings. For the equivalent `occ` command or an explanation of the Deploy daemon parameters, see [DaemonConfig registration](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/tech_details/Deployment.html#occ-daemon-config-registration)
.
### Docker Socket Proxy[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#docker-socket-proxy "Link to this heading")
For development and testing locally, the simplest way is to use the [Nextcloud AppAPI DSP HTTP](https://github.com/nextcloud/docker-socket-proxy?tab=readme-ov-file#httplocal)
.
In Place of a Conclusion[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#in-place-of-a-conclusion "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are several make commands available to ease frequent development actions.
To see the complete list, execute `make help`.
### Docker remote API[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#docker-remote-api "Link to this heading")
The Docker Engine remote API can be easily configured via `make dock2port` command. The command will create a docker container to provide remote Docker Engine API.
Afterward, register DaemonConfigs in Nextcloud using `make dock-port` command.
### Docker by socket[](https://docs.nextcloud.com/server/stable/developer_manual/exapp_development/DevSetup.html#docker-by-socket "Link to this heading")
For Docker via socket, use the command `make dock-sock`. This registers DaemonConfigs in Nextcloud for the default socket connection (`/var/run/docker.sock`).
Make sure that socket has enough permissions for Nextcloud and webserver user to access it and actually forwarded to the container:
...
volumes:
...
\- /var/run/docker.sock:/var/run/docker.sock
...
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Static analysis — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* Static analysis
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/static-analysis.rst)
* * *
Static analysis[](https://docs.nextcloud.com/server/31/developer_manual/server/static-analysis.html#static-analysis "Link to this heading")
=============================================================================================================================================
PHP static analysis[](https://docs.nextcloud.com/server/31/developer_manual/server/static-analysis.html#php-static-analysis "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------
In the server repository psalm is used for static analysis of the PHP code.
### Required PHP extensions[](https://docs.nextcloud.com/server/31/developer_manual/server/static-analysis.html#required-php-extensions "Link to this heading")
The following PHP extensions are required to be installed and enabled to make psalm work:
* acpu
* curl
* ftp
* gd
* iconv
* imagick
* json
* ldap
* libxml
* mbstring
* openssl
* pdo
* simplexml
* sysvsem
* xmlreader
* zip
Some of these are for optional features, but are still required to validate the code.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Setting up dev environment — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [ExApp development](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/index.html)
* Setting up dev environment
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/exapp_development/DevSetup.rst)
* * *
Setting up dev environment[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#setting-up-dev-environment "Link to this heading")
=======================================================================================================================================================================
AppAPI development requires a Nextcloud development environment setup. We highly recommend using [Julius Knorr’s Docker setup](https://github.com/juliusknorr/nextcloud-docker-dev)
for this. For an alternate environment without using Docker, please refer to the setup instructions in [Getting started](https://docs.nextcloud.com/server/32/developer_manual/getting_started/devenv.html)
.
Suggested IDE: **PhpStorm**, though you can certainly use any IDE of your preference such as **VS Code** or **Vim**.
Install AppAPI[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#install-appapi "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
All ExApps require the [AppAPI](https://apps.nextcloud.com/apps/app_api)
Nextcloud app as a dependency. As of Nextcloud version 30.0.1, AppAPI is automatically installed by default. If you prefer, you can also build the latest development version of AppAPI from the source code, in which case uninstall the release version of AppAPI and perform the following steps.
Clone the latest main branch:
> git clone https://github.com/nextcloud/app\_api.git && cd app\_api
or clone a specific version by specifying the version tag:
> git clone https://github.com/nextcloud/app\_api.git \--branch && cd app\_api
where `` is the version you want to install.
Then, build frontend assets in development mode:
> npm ci && npm run dev
Enable AppAPI from the directory where the `occ` command resides:
> ./occ app:enable \--force app\_api
### Deploy daemons types[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#deploy-daemons-types "Link to this heading")
There are two types of Deploy daemons that can be used for development and testing of ExApps:
1. `manual_install`: This type of Deploy daemon is running manually in the host machine. This is useful for ExApp development as you can run your ExApp directly on the host.
2. `docker_install`: This type of Deploy daemon is running in a Docker container.
You can register (create) these daemons in the AppAPI admin settings. For the equivalent `occ` command or an explanation of the Deploy daemon parameters, see [DaemonConfig registration](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/tech_details/Deployment.html#occ-daemon-config-registration)
.
### Docker Socket Proxy[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#docker-socket-proxy "Link to this heading")
For development and testing locally, the simplest way is to use the [Nextcloud AppAPI DSP HTTP](https://github.com/nextcloud/docker-socket-proxy?tab=readme-ov-file#httplocal)
.
In Place of a Conclusion[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#in-place-of-a-conclusion "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
There are several make commands available to ease frequent development actions.
To see the complete list, execute `make help`.
### Docker remote API[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#docker-remote-api "Link to this heading")
The Docker Engine remote API can be easily configured via `make dock2port` command. The command will create a docker container to provide remote Docker Engine API.
Afterward, register DaemonConfigs in Nextcloud using `make dock-port` command.
### Docker by socket[](https://docs.nextcloud.com/server/32/developer_manual/exapp_development/DevSetup.html#docker-by-socket "Link to this heading")
For Docker via socket, use the command `make dock-sock`. This registers DaemonConfigs in Nextcloud for the default socket connection (`/var/run/docker.sock`).
Make sure that socket has enough permissions for Nextcloud and webserver user to access it and actually forwarded to the container:
...
volumes:
...
\- /var/run/docker.sock:/var/run/docker.sock
...
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Back-end code — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* Back-end code
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/code-back-end.rst)
* * *
Back-end code[](https://docs.nextcloud.com/server/31/developer_manual/server/code-back-end.html#back-end-code "Link to this heading")
=======================================================================================================================================
When changing back-end PHP code, in general, no additional steps are needed before checking in.
However, if new files were created, you will need to run the following command to update the autoloader files:
build/autoloaderchecker.sh
After that, please also include the autoloader file changes in your commits.
Compatibility documentation[](https://docs.nextcloud.com/server/31/developer_manual/server/code-back-end.html#compatibility-documentation "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
* New APIs (interfaces, constants, methods, classes, traits, enums) added to the public namespace `OCP` have to be annotated with a `@since X.Y.Z` attribute of the version it was added in.
* When it is backported the version should be adjusted to the X.Y.Z of the stable version it was backported in only in that stable branch. The master branch should still contain the newest Major version shipping the API.
* Once an API was shipped, unless it is marked as experimental, it has to be deprecated in similar fashion using `@deprecated X.Y.Z` for 3 years (9 Nextcloud releases) before it can be removed. Deprecations have to be clearly documented in the [App upgrade guide](https://docs.nextcloud.com/server/31/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html#app-upgrade-guide)
for the upcoming Major version.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Dependency injection — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/32/developer_manual/basics/index.html)
* Dependency injection
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/dependency_injection.rst)
* * *
Dependency injection[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#dependency-injection "Link to this heading")
============================================================================================================================================================
The App Framework assembles the application by using a container based on the software pattern [Dependency Injection](https://en.wikipedia.org/wiki/Dependency_injection)
. This makes the code easier to test and thus easier to maintain.
If you are unfamiliar with this pattern, watch the following video:
* [Google Clean Code Talks](https://www.youtube.com/watch?v=RlfLCWKxHJ0)
Dependency injection[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#id2 "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------
Dependency Injection sounds pretty complicated but it just means: Don’t put new dependencies in your constructor or methods but pass them in. So this:
use OCP\\IDBConnection;
// without dependency injection
class AuthorMapper {
private IDBConnection $db;
public function \_\_construct() {
$this\->db \= new Db();
}
}
would turn into this by using Dependency Injection:
use OCP\\IDBConnection;
// with dependency injection
class AuthorMapper {
private IDBConnection $db;
public function \_\_construct(IDBConnection $db) {
$this\->db \= $db;
}
}
Controller injection[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#controller-injection "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------
For controllers it’s possible to also have dependencies injected into methods.
lib/Controller/ApiController.php[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#id4 "Link to this code")
foo(); }
public function bar(BarService $service) { $service\->bar(); }
}
Using a container[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#using-a-container "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
Note
Please do use automatic dependency injection (see below). For most apps there is no need to register services manually.
Passing dependencies into the constructor rather than instantiating them in the constructor has the following drawback: Every line in the source code where **new AuthorMapper** is being used has to be changed, once a new constructor argument is being added to it.
The solution for this particular problem is to limit the **new AuthorMapper** to one file, the container. The container contains all the factories for creating these objects and is configured in `lib/AppInfo/Application.php`.
Nextcloud 20 and later uses the [PSR-11 standard](https://docs.nextcloud.com/server/32/developer_manual/digging_deeper/psr.html#psr11)
for the container interface, so working with the container might feel familiar if you’ve worked with other php applications before that also adhere to the convention.
To add the app’s classes simply open the `lib/AppInfo/Application.php` and use the **IRegistrationContext::registerService** method:
registerService(AuthorController::class, function(ContainerInterface $c): AuthorController {
return new AuthorController(
$c\->get('appName'),
$c\->get(Request::class),
$c\->get(AuthorService::class)
);
});
/\*\*
\* Services
\*/
$context\->registerService(AuthorService::class, function(ContainerInterface $c): AuthorService {
return new AuthorService(
$c\->get(AuthorMapper::class)
);
});
/\*\*
\* Mappers
\*/
$context\->registerService(AuthorMapper::class, function(ContainerInterface $c): AuthorMapper {
return new AuthorMapper(
$c\->get(IDBConnection::class)
);
});
}
}
How the container works[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#how-the-container-works "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------
The container works in the following way:
* [A request comes in and is matched against a route](https://docs.nextcloud.com/server/32/developer_manual/basics/routing.html)
(for the AuthorController in this case)
* The matched route queries **AuthorController** service from the container:
return new AuthorController(
$c->get('appName'),
$c->get(Request::class),
$c->get(AuthorService::class)
);
* The **appName** is queried and returned from the base class
* The **Request** is queried and returned from the server container
* **AuthorService** is queried:
$container->registerService(AuthorService::class, function(ContainerInterface $c): AuthorService {
return new AuthorService(
$c->get(AuthorMapper::class)
);
});
* **AuthorMapper** is queried:
$container->registerService(AuthorMappers::class, function(ContainerInterface $c): AuthorMapper {
return new AuthorService(
$c->get(IDBConnection::class)
);
});
* The **database connection** is returned from the server container
* Now **AuthorMapper** has all of its dependencies and the object is returned
* **AuthorService** gets the **AuthorMapper** and returns the object
* **AuthorController** gets the **AuthorService** and finally the controller can be instantiated and the object is returned
So basically the container is used as a giant factory to build all the classes that are needed for the application. Because it centralizes all the creation of objects (the **new Class()** lines), it is very easy to add new constructor parameters without breaking existing code: only the **\_\_construct** method and the container line where the **new** is being called need to be changed.
Use automatic dependency assembly (recommended)[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#use-automatic-dependency-assembly-recommended "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In Nextcloud it is possible to build classes and their dependencies without having to explicitly register them on the container, as long as the container can [reflect](https://www.php.net/manual/en/book.reflection.php)
the constructor and look up the parameters by their type. This concept is widely known as _auto-wiring_.
### How does auto-wiring work[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#how-does-auto-wiring-work "Link to this heading")
Automatic assembly creates new instances of classes just by looking at the class name and its constructor parameters. For each constructor parameter the type or the argument name is used to query the container, e.g.:
* **SomeType $type** will use **$container->get(SomeType::class)**
* **$variable** will use **$container->get(‘variable’)**
If all constructor parameters are resolved, the class will be created, saved as a service and returned.
So basically the following is now possible:
class \= $class;
$this\->appName \= $appName;
}
}
$app \= new \\OCP\\AppFramework\\App('myapp');
$class2 \= $app\->getContainer()\->get(MyTestClass2::class);
$class2 instanceof MyTestClass2; // true
$class2\->class instanceof MyTestClass; // true
$class2\->appName \=== 'myname'; // true
$class2 \=== $app\->getContainer()\->get(MyTestClass2::class); // true
Note
$appName is resolved because the container registered a parameter under the key ‘appName’ which will return the app id.
### How does it affect the request lifecycle[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#how-does-it-affect-the-request-lifecycle "Link to this heading")
* A request comes in
* All apps’ **routes.php** files are loaded
* If a **routes.php** file returns an array, and an **appname/lib/AppInfo/Application.php** exists, include it, create a new instance of **\\OCA\\AppName\\AppInfo\\Application.php** and register the routes on it. That way a container can be used while still benefitting from the new routes behavior
* If a **routes.php** file returns an array, but there is no **appname/lib/AppInfo/Application.php**, create a new \\OCP\\AppFramework\\App instance with the app id and register the routes on it
* A request is matched for the route, e.g. with the name **page#index**
* The appropriate container is being queried for the entry PageController (to keep backwards compatibility)
* If the entry does not exist, the container is queried for OCA\\AppName\\Controller\\PageController and if no entry exists, the container tries to create the class by using [reflection](https://www.php.net/manual/en/book.reflection.php)
on its constructor parameters
### How does this affect controllers[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#how-does-this-affect-controllers "Link to this heading")
The only thing that needs to be done to add a route and a controller method is now:
**myapp/appinfo/routes.php**
\[\
\['name' \=> 'page#index', 'url' \=> '/', 'verb' \=> 'GET'\],\
\]\];
**myapp/appinfo/lib/Controller/PageController.php**
registerParameter('TableName', 'my\_app\_table');
// the interface is called IAuthorMapper and AuthorMapper implements it
$context\->registerService(IAuthorMapper::class, function (ContainerInterface $c): AuthorMapper {
return $c\->get(AuthorMapper::class);
});
// Less verbose alternative
$context\->registerServiceAlias(IAuthorMapper::class, AuthorMapper::class);
}
}
### Predefined core services[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#predefined-core-services "Link to this heading")
The following parameter names and type hints can be used to inject core services instead of using **$container->getServer()->getServiceX()**
Parameters:
* **appName**: The app id
* **userId**: The id of the current user
* **webRoot**: The path to the Nextcloud installation
Aliases:
* **AppName**: resolves to `appName` (deprecated)
* **Request**: resolves to `\OCP\IRequest`
* **ServerContainer**: resolves to `\OCP\IServerContainer` (deprecated)
* **UserId**: resolves to `userId` (deprecated)
* **WebRoot**: resolves to `webRoot` (deprecated)
Types:
* `\OCP\IAppConfig`
* `\OCP\IAppManager`
* `\OCP\IAvatarManager`
* `\OCP\Activity\IManager`
* `\OCP\ICache`
* `\OCP\ICacheFactory`
* `\OCP\IConfig`
* `\OCP\AppFramework\Utility\IControllerMethodReflector`
* `\OCP\Contacts\IManager`
* `\OCP\IDateTimeZone`
* `\OCP\IDBConnection`
* `\OCP\Diagnostics\IEventLogger`
* `\OCP\Diagnostics\IQueryLogger`
* `\OCP\Files\Config\IMountProviderCollection`
* `\OCP\Files\IRootFolder`
* `\OCP\IGroupManager`
* `\OCP\IL10N`
* `\OCP\BackgroundJob\IJobList`
* `\OCP\INavigationManager`
* `\OCP\IPreview`
* `\OCP\IRequest`
* `\OCP\AppFramework\Utility\ITimeFactory`
* `\OCP\ITagManager`
* `\OCP\ITempManager`
* `\OCP\Route\IRouter`
* `\OCP\ISearch`
* `\OCP\Security\ICrypto`
* `\OCP\Security\IHasher`
* `\OCP\Security\ISecureRandom`
* `\OCP\IURLGenerator`
* `\OCP\IUserManager`
* `\OCP\IUserSession`
* `\Psr\Container\ContainerInterface`
* `\Psr\Log\LoggerInterface`
### How to enable it[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#how-to-enable-it "Link to this heading")
To make use of this new feature, the following things have to be done:
* **appinfo/info.xml** requires to provide another field called **namespace** where the namespace of the app is defined. The required namespace is the one which comes after the top level namespace **OCA\\**, e.g.: for **OCA\\MyBeautifulApp\\Some\\OtherClass** the needed namespace would be **MyBeautifulApp** and would be added to the info.xml in the following way:
MyBeautifulApp
* **appinfo/routes.php**: Instead of creating a new Application class instance, simply return the routes array like:
\[\
\['name' \=> 'page#index', 'url' \=> '/', 'verb' \=> 'GET'\],\
\]\];
Note
A namespace tag is required because you can not deduce the namespace from the app id
Which classes should be added[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#which-classes-should-be-added "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
In general all of the app’s controllers need to be registered inside the container. Then the following question is: What goes into the constructor of the controller? Pass everything into the controller constructor that matches one of the following criteria:
* It does I/O (database, write/read to files)
* It is a global (e.g. $\_POST, etc. This is in the request class by the way)
* The output does not depend on the input variables (also called [impure function](https://en.wikipedia.org/wiki/Pure_function)
), e.g. time, random number generator
* It is a service, basically it would make sense to swap it out for a different object
What not to inject:
* It is pure data and has methods that only act upon it (arrays, data objects)
* It is a [pure function](https://en.wikipedia.org/wiki/Pure_function)
Optional services[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#optional-services "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
Added in version 28.
If an injected dependency can’t be found or build, an exception is thrown. This can be avoided by using the a nullable type notation for a dependency:
namespace OCA\\MyApp\\MyService;
use Some\\Service;
class MyService {
public function \_\_construct(private ?Service $service) { }
}
If `\Some\Service` exists and can be built, it will be injected. Else `MyService` will receive `null`.
Accessing the container from anywhere[](https://docs.nextcloud.com/server/32/developer_manual/basics/dependency_injection.html#accessing-the-container-from-anywhere "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
Sometimes it can be hard to inject some service inside legacy code, in these cases you can use `OCPServer::get(MyService::class)`. This should only be used as the last resort, as this makes your code more complicated to unit test and is considered an anti-pattern.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Navigation and pre-app configuration — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html)
* Navigation and pre-app configuration
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/init.rst)
* * *
Navigation and pre-app configuration[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html#navigation-and-pre-app-configuration "Link to this heading")
=========================================================================================================================================================================================
Adding a navigation entry[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html#adding-a-navigation-entry "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
Navigation entries for apps can be created by adding a navigation section to the `appinfo/info.xml` file, containing the name, order and route the navigation entry should link to. For details on the XML schema check the [app store documentation](https://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml)
.
MyAppmyapp.page.index0
Initialization events[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/init.html#initialization-events "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------
Often apps do not need to load their JavaScript and CSS on every page. For this purpose there are several events emitted that an app can act upon.
* `OCA\Files::loadAdditionalScripts` (string): loaded on the files list page
* `OCA\Files_Sharing::loadAdditionalScripts` (string): loaded on the public sharing page
* `OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth` (string): loaded on the public share authentication page
* `OCP\AppFramework\Http\TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS` (constant): loaded when a template response is finished
* `OCP\AppFramework\Http\TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS_LOGGEDIN` (constant): loaded when a template response is finished for a logged in user
You can subscribe listeners to these events in the [bootstrapping code](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#bootstrapping)
of the app. See the [events documentation](https://docs.nextcloud.com/server/stable/developer_manual/basics/events.html#events)
for more details on the event dispatcher and available events.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Nextcloud architecture — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* Nextcloud architecture
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/architecture/index.rst)
* * *
Nextcloud architecture[](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/index.html#nextcloud-architecture "Link to this heading")
==============================================================================================================================================================
* [Nextcloud filesystem API](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html)
* [High level overview](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#high-level-overview)
* [Filesystem layer](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#filesystem-layer)
* [Storage layer](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#storage-layer)
* [Storage/Cache wrappers](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#storage-cache-wrappers)
* [Code Map](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#code-map)
* [AppData](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#appdata)
* [Cache](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#cache)
* [Mount](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#mount)
* [Node](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#node)
* [ObjectStorage](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#objectstorage)
* [SimpleFS](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#simplefs)
* [Storage](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#storage)
* [Streams](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#streams)
* [Type](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#type)
* [View.php](https://docs.nextcloud.com/server/31/developer_manual/server/architecture/files.html#view-php)
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# External API — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* External API
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/externalapi.rst)
* * *
External API[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#external-api "Link to this heading")
===================================================================================================================================
Introduction[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#introduction "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------
The external API inside Nextcloud allows third party developers to access data provided by Nextcloud apps. Nextcloud follows the [Open Collaboration Services specification](https://open-collaboration-services.org/)
.
Usage[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#usage "Link to this heading")
---------------------------------------------------------------------------------------------------------------------
### Registering methods[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#registering-methods "Link to this heading")
Methods are registered inside the `appinfo/routes.php` by returning an array holding the endpoint meta data.
\[\
// Apps\
\['name' \=> 'Bar#getFoo', 'url' \=> '/foobar', 'verb' \=> 'GET'\],\
\],\
\];
### Returning data[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#returning-data "Link to this heading")
Once the API backend has matched your URL, your callable function as defined in **BarController::getFoo** will be executed. The AppFramework will make sure that send parameters are provided to the method based on its declaration.
Be sure to extend the `OCP\AppFramework\OCSController` from the AppFramework. Your functions then should returns a `OCP\AppFramework\Http\DataResponse`. The AppFramework will then take care formatting the response properly.
### Exceptions[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#exceptions "Link to this heading")
To throw an exception to the user in the OCS response. You can throw an `OCP\AppFramework\OCS\OCSException`. You can set the message and code.
There are 3 commonly used exceptions already available:
* `OCSBadRequestException`
* `OCSForbiddenException`
* `OCSNotFoundException`
### Authentication & basics[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#authentication-basics "Link to this heading")
The requests to the OCS endpoint often have to be authenticated.
> `curl -u user:password https://example.com/ocs/v2.php/apps/yourapp/foobar`
### Output[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#output "Link to this heading")
The output defaults to XML. If you want to get JSON append this to the URL:
?format=json
Or set the proper Accept header:
Accept: application/json
Output from the application is wrapped inside a **data** element:
**XML**:
ok200
**JSON**:
{
"ocs": {
"meta": {
"status": "ok",
"statuscode": 200,
"message": null
},
"data": {
// data here
}
}
}
### Statuscodes[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#statuscodes "Link to this heading")
The statuscode can be any of the following numbers:
* **200** - successful
* **996** - server error
* **401** - not authorized
* **404** - not found
* **999** - unknown error
### Changing API and backwards compatibility[](https://docs.nextcloud.com/server/31/developer_manual/server/externalapi.html#changing-api-and-backwards-compatibility "Link to this heading")
We aim to keep our API as stable as possible to avoid breaking third-party apps. Before an API is allowed to be removed, it should be marked as deprecated for at least 3 years (9 Nextcloud releases) before it gets removed.
Changing the API [should be discussed in a github issue in our server repo](https://github.com/nextcloud/server/issues)
. A pull request is most welcome.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Unit-Testing — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* Unit-Testing
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/unit-testing.rst)
* * *
Unit-Testing[](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html#unit-testing "Link to this heading")
====================================================================================================================================
PHP unit testing[](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html#php-unit-testing "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------
### Getting PHPUnit[](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html#getting-phpunit "Link to this heading")
Nextcloud uses PHPUnit >= 8.5 for unit testing.
PHPUnit documentation: [https://phpunit.de/documentation.html](https://phpunit.de/documentation.html)
### Writing PHP unit tests[](https://docs.nextcloud.com/server/31/developer_manual/server/unit-testing.html#writing-php-unit-tests "Link to this heading")
To get started, do the following:
* Create a directory called `tests` in the top level of your application
* Create a PHP file in the directory and `require_once` your class which you want to test
Then you can simply run the created test with **phpunit**.
Note
If you use Nextcloud functions in your class under test (i.e., OC::getUser()) you’ll need to bootstrap Nextcloud or use dependency injection.
Note
You’ll most likely run your tests under a different user than the Web server. This might cause problems with your PHP settings (i.e., open\_basedir) and requires you to adjust your configuration.
An example for a simple test would be:
`/srv/http/nextcloud/apps/myapp/tests/testaddtwo.php`
testMe \= new \\OCA\\Myapp\\TestMe();
}
public function testAddTwo(){
$this\->assertEquals(5, $this\->testMe\->addTwo(3));
}
}
`/srv/http/nextcloud/apps/myapp/lib/testme.php`
array (
0 \=> array (
'path' \=> '/var/www/html/apps',
'url' \=> '/apps',
'writable' \=> false,
),
1 \=> array (
'path' \=> '/var/www/html/apps-extra',
'url' \=> '/apps-extra',
'writable' \=> false,
),
),
Finally, clone the app to which you would like to contribute inside the apps-extra folder. For example:
> git clone [https://github.com/nextcloud/cookbook.git](https://github.com/nextcloud/cookbook.git)
Enable the app[](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html#enable-the-app "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------
The app can now be enabled on the Nextcloud apps page.
App architecture[](https://docs.nextcloud.com/server/32/developer_manual/app_development/intro.html#app-architecture "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------
The following directories have now been created:
* **appinfo/**: Contains app metadata and configuration
* **css/**: Contains the CSS
* **img/**: Contains icons and images
* **js/**: Contains the JavaScript files
* **lib/**: Contains the PHP class files of your app
* **src/**: Contains the source code of your vue.js app
* **templates/**: Contains the templates
* **tests/**: Contains the tests
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Navigation and pre-app configuration — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/32/developer_manual/app_development/index.html)
* Navigation and pre-app configuration
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/init.rst)
* * *
Navigation and pre-app configuration[](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html#navigation-and-pre-app-configuration "Link to this heading")
=====================================================================================================================================================================================
Adding a navigation entry[](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html#adding-a-navigation-entry "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------------
Navigation entries for apps can be created by adding a navigation section to the `appinfo/info.xml` file, containing the name, order and route the navigation entry should link to. For details on the XML schema check the [app store documentation](https://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml)
.
MyAppmyapp.page.index0
Initialization events[](https://docs.nextcloud.com/server/32/developer_manual/app_development/init.html#initialization-events "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------
Often apps do not need to load their JavaScript and CSS on every page. For this purpose there are several events emitted that an app can act upon.
* `OCA\Files::loadAdditionalScripts` (string): loaded on the files list page
* `OCA\Files_Sharing::loadAdditionalScripts` (string): loaded on the public sharing page
* `OCA\Files_Sharing::loadAdditionalScripts::publicShareAuth` (string): loaded on the public share authentication page
* `OCP\AppFramework\Http\TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS` (constant): loaded when a template response is finished
* `OCP\AppFramework\Http\TemplateResponse::EVENT_LOAD_ADDITIONAL_SCRIPTS_LOGGEDIN` (constant): loaded when a template response is finished for a logged in user
You can subscribe listeners to these events in the [bootstrapping code](https://docs.nextcloud.com/server/32/developer_manual/app_development/bootstrap.html#bootstrapping)
of the app. See the [events documentation](https://docs.nextcloud.com/server/32/developer_manual/basics/events.html#events)
for more details on the event dispatcher and available events.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Logging — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/31/developer_manual/basics/index.html)
* Logging
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/logging.rst)
* * *
Logging[](https://docs.nextcloud.com/server/31/developer_manual/basics/logging.html#logging "Link to this heading")
=====================================================================================================================
The logger is present by default in the container. The app that is logging is set automatically. Nextcloud uses a [PSR3](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/psr.html#psr3)
logger.
The logger can be used in the following way:
logger \= $logger;
$this\->appName \= $appName;
}
public function log($message) {
$this\->logger\->error($message, \['extra\_context' \=> 'my extra context'\]);
}
}
In cases where you can not [inject](https://docs.nextcloud.com/server/31/developer_manual/basics/dependency_injection.html#id2)
a logger into a class, you can use the `\OCP\Log\logger` function to acquire a logger instance. As a first argument you need to pass the app ID.
warning('look, no dependency injection');
Admin audit logging[](https://docs.nextcloud.com/server/31/developer_manual/basics/logging.html#admin-audit-logging "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------
If you want to log things less for system administration but for compliance reasons, e.g. who accessed which file, who changed the password of an item or made it public, the [admin audit log](https://docs.nextcloud.com/server/31/admin_manual/configuration_server/logging_configuration.html#admin-audit-log)
is the correct place.
You can easily add a log by simply emitting an `OCP\Log\Audit\CriticalActionPerformedEvent` event:
'My App ID'\]
);
$dispatcher\->dispatchTyped($event);
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Dependency management — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html)
* Dependency management
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/dependency_management.rst)
* * *
Dependency management[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#dependency-management "Link to this heading")
============================================================================================================================================================================
You can leverage existing software packages to build a Nextcloud app.
Composer[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#composer "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
You can add 3rd party php packages with [Composer](https://getcomposer.org/)
. Composer will download the specified packages to a directory of your choice, typically to `/vendor`. In order to benefit from Composer’s autoloader, you’ll want to add a `require_once` to the `register` method of your `Application` class in the [bootstrapping](https://docs.nextcloud.com/server/stable/developer_manual/app_development/bootstrap.html#bootstrapping)
code of your app.
### Remove unneeded files from packages[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#remove-unneeded-files-from-packages "Link to this heading")
It is heavily recommended to remove files that are not required in production from the final packages. This especially, but not exclusively, refers to:
* Developer files, e.g. `/Makefile`
* CI workflows, e.g. `/.github`
* Test assets, e.g. `/tests`
* Configuration of development tools, e.g. `/phpunit.xml`, `/psalm.xml`
* Git or other version control code, e.g. `/.git`
You can check the [Server’s .gitignore](https://github.com/nextcloud/3rdparty/blob/master/.gitignore)
file for more inspiration.
### Dependency hell[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#dependency-hell "Link to this heading")
Be careful with which packages you add to an app. PHP can not load two version of the same class twice, hence there can be conflicts between Nextcloud Server and an app or between two or more apps if they require the same package. So try to keep the number of production dependencies to a minimum and see [Development tools](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#app-composer-bin-tools)
.
Alternatively you can use \[composer-bin-plugin\]([https://github.com/bamarni/composer-bin-plugin](https://github.com/bamarni/composer-bin-plugin)
) to avoid dependency conflicts between apps.
1. Install composer-bin-plugin according to their docs.
> composer require \--dev bamarni/composer-bin-plugin
2. Install the tools you need in the vendor-bin directory.
> composer bin psalm require \--dev psalm/phar
> composer bin psalm require \--dev nextcloud/ocp:dev-master
3. Adjust some config (see below)
* Add in composer.json:
composer.json[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#id2 "Link to this code")
{
"extra": {
"bamarni-bin": {
"bin-links": true,
"forward-command": true
}
}
}
* Add in composer.json:
composer.json[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#id3 "Link to this code")
{
"scripts": {
"post-install-cmd": \[\
"\[ $COMPOSER\_DEV\_MODE -eq 0 \] || composer bin all install --ansi"\
\],
"post-update-cmd": \[\
"\[ $COMPOSER\_DEV\_MODE -eq 0 \] || composer bin all update --ansi"\
\]
}
}
* Adjust psalm.xml:
* Ensure the schemaLocation is correct:
psalm.xml[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#id4 "Link to this code")
xsi:schemaLocation="https://getpsalm.org/schema/config vendor-bin/psalm/vendor/vimeo/psalm/config.xsd"
* Ensure it has something like this:
psalm.xml[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#id5 "Link to this code")
* Adjust .php-cs-fixer.dist.php
.php-cs-fixer.dist.php[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#id6 "Link to this code")
require\_once \_\_DIR\_\_ . '/vendor-bin/cs-fixer/vendor/autoload.php';
#### Conflict example[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#conflict-example "Link to this heading")
To illustrate the problem imagine app _A_ depends on package _foo_ in version 1, app _B_ depends on package _foo_ in version 2. The package _foo_ had a breaking change to which app _B_ has been adjusted, _A_ uses the old API.
Both apps ship a Composer autoloader that autoloads the _foo_ functions and classes. There is a race between the two autoloaders. If _A_’s autoloader is asked to load the class first, then v1 will be used. If _B_’s autoloader loads functions and classes first it will be v2. In some scenarios there might be classes of v1 and v2 when autoloaders are invoked without a defined order.
Depending on which functions and classes are loaded, app _A_ might work or break. The same applies to _B_.
### Development tools[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#development-tools "Link to this heading")
It is very common for an app to use CLI tools for syntax checks, testing and building. Since many tools depend on common Composer packages like `psr/*` and `symfony/console`, it is likely that apps produce a [dependency hell](https://docs.nextcloud.com/server/stable/developer_manual/app_development/dependency_management.html#app-composer-dependency-hell)
on development environments.
The dependency hell for CLI tools can be avoided by using the _Composer bin plugin_. It’s a composer plugin that puts development dependencies into sub directorory with a dedicated autoloader. That autoloader is only used if the CLI tool is used. For Nextcloud apps this means two apps can use conflicting versions of one tool. Moreover dependency conflicts between the tools of one app are no longer an issue.
Tools known to be problematic that should be moved into bin plugin directories include
* `friendsofphp/php-cs-fixer`
* `phpunit/phpunit`
* `vimeo/psalm`
Please see the [package page](https://packagist.org/packages/bamarni/composer-bin-plugin)
for up-to-date installation instructions.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# App metadata — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/32/developer_manual/app_development/index.html)
* App metadata
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/info.rst)
* * *
App metadata[](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html#app-metadata "Link to this heading")
=====================================================================================================================================
The `appinfo/info.xml` contains metadata about the app. A detailed documentation can be found at the [app store documentation](https://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml)
.
The info.xml is validated using an XML Schema which can be accessed [online](https://apps.nextcloud.com/schema/apps/info.xsd)
.
A minimum valid **info.xml** would look like this:
appinfo/info.xml[](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html#id2 "Link to this code")
newsNewsAn RSS/Atom feed readerAn RSS/Atom feed reader8.8.2AGPL-3.0-or-laterBernhard Posseltmultimediahttps://github.com/nextcloud/news/issues
A full blown example would look like this (needs to be utf-8 encoded):
appinfo/info.xml[](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html#id3 "Link to this code")
newsNachrichtenNewsAn RSS/Atom feed reader# Description\\nAn RSS/Atom feed reader8.8.2AGPL-3.0-or-laterBernhard PosseltAlessandro CosentinoJan-Christoph Borchardthttps://github.com/nextcloud/news/wiki#user-documentationhttps://github.com/nextcloud/news#readmehttps://github.com/nextcloud/news/wiki#developer-documentationmultimediatoolshttps://github.com/nextcloud/newshttps://your.forum.comhttps://github.com/nextcloud/news/issueshttps://github.com/nextcloud/newshttps://example.com/1.pnghttps://example.com/2.jpgpgsqlsqlitemysqlgreplslibxmlcurlSimpleXMLiconvOCA\\DAV\\CardDAV\\Sync\\SyncJobOCA\\DAV\\Migration\\ClassificationOCA\\DAV\\Migration\\ClassificationOCA\\DAV\\Migration\\GenerateBirthdaysOCA\\DAV\\Migration\\GenerateBirthdaysOCA\\DAV\\Migration\\GenerateBirthdaysOCA\\AuthF\\TwoFactor\\ProviderA\\Php\\ClassOCA\\Theming\\Settings\\AdminOCA\\Theming\\Settings\\SectionOCA\\Files\\Activity\\Settings\\FavoriteActionOCA\\Files\\Activity\\Settings\\FileChangedOCA\\Files\\Activity\\Settings\\FileCreatedOCA\\Files\\Activity\\Settings\\FileDeletedOCA\\Files\\Activity\\Settings\\FileFavoriteOCA\\Files\\Activity\\Settings\\FileRestoredOCA\\Files\\Activity\\Filter\\FileChangesOCA\\Files\\Activity\\Filter\\FavoritesOCA\\Files\\Activity\\FavoriteProviderOCA\\Files\\Activity\\ProviderfilesFilesfiles.view.index0app.svglinkOCA\\Circles\\Collaboration\\v1\\CollaboratorSearchPlugin
The following tags are validated and used in the following way:
id
* required
* must contain only lowercase ASCII characters and underscore
* must match the first folder in the archive
* will be used to identify the app
name
* required
* must occur at least once with **lang=”en”** or no lang attribute
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app detail page
summary
* optional
* if not provided the description element’s text will be used
* must occur at least once with **lang=”en”** or no lang attribute
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app list page as short description
description
* required
* must occur at least once with **lang=”en”** or no lang attribute
* can contain Markdown
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app detail page
version
* required
* must be a [semantic version](http://semver.org/)
without build metadata, e.g. 9.0.1 or 9.1.0-alpha.1
* [more info on app versioning](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/release_process.html#app-versioning)
licence
* required
* can occur multiple times with different licenses
* must contain one of the following licenses (for apps targeting v31 or higher, see the [SPDX License List](https://spdx.org/licenses/)
for details):
> * **AGPL-3.0-only**
>
> * **AGPL-3.0-or-later**
>
> * **Apache-2.0**
>
> * **GPL-3.0-only**
>
> * **GPL-3.0-or-later**
>
> * **MIT**
>
> * **MPL-2.0**
>
* (deprecated, for apps targeting v30 or lower) the following shorthand aliases are also used:
> * **agpl** (AGPL-3.0)
>
> * **apache** (Apache-2.0)
>
> * **gpl3** (GPL-3.0)
>
> * **mit** (MIT)
>
> * **mpl** (MPL-2.0)
>
author
* required
* can occur multiple times with different authors
* can contain a **mail** attribute which must be an email
* can contain a **homepage** which must be a URL
* will not (yet) be rendered on the App Store
* will be provided through the REST API
documentation/user
* optional
* must contain a URL to the user documentation
* will be rendered on the app detail page
documentation/admin
* optional
* must contain a URL to the admin documentation
* will be rendered on the app detail page
documentation/developer
* optional
* must contain a URL to the developer documentation
* will be rendered on the app detail page
category
* optional
* if not provided the category **tools** will be used
* must contain one of the following values:
> * **customization**
>
> * **files**
>
> * **games**
>
> * **integration**
>
> * **monitoring**
>
> * **multimedia**
>
> * **office**
>
> * **organization**
>
> * **security**
>
> * **social**
>
> * **tools**
>
* old categories are migrated:
> * **auth** will be converted to **security**
>
* can occur more than once with different categories
website
* optional
* must contain a URL to the project’s homepage
* will be rendered on the app detail page
discussion
* optional
* must contain a URL to the project’s discussion page/forum
* will be rendered on the app detail page as the “ask question or discuss” button
* if absent, it will default to our forum at [https://help.nextcloud.com/](https://help.nextcloud.com/)
bugs
* required
* must contain a URL to the project’s bug tracker
* will be rendered on the app detail page
repository
* optional
* must contain a URL to the project’s repository
* can contain a **type** attribute, **git**, **mercurial**, **subversion** and **bzr** are allowed values, defaults to **git**
* currently not used
screenshot
* optional
* must contain an HTTPS URL to an image
* can contain a **small-thumbnail** attribute which must contain an https url to an image. This image will be used as small preview (e.g. on the app list overview). Keep it small so it renders fast
* will be rendered on the app list and detail page in the given order
dependencies/php
* optional
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
* can contain a **min-int-size** attribute, 32 or 64 are allowed as valid values
* will be rendered on the app releases page
dependencies/database
* optional
* must contain the database name as text, **sqlite**, **pgsql** and **mysql** are allowed as valid values
* can occur multiple times with different databases
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
* will be rendered on the app releases page
dependencies/command
* optional
* must contain a linux command as text value
* can occur multiple times with different commands
* will be rendered on the app releases page
dependencies/lib
* optional
* will be rendered on the app releases page
* must contain a required php extension
* can occur multiple times with different php extensions
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
dependencies/nextcloud
* required
* must contain a **min-version** attribute (maximum 3 digits separated by dots)
* must contain a **max-version** attribute (maximum 3 digits separated by dots)
Note
Dependencies dependencies/php, dependencies/database and dependencies/lib are checked at installation time (not on update time), hence applications need to stick to the dependencies supported by a major version of Nextcloud the moment an app releases support for that version, i.e. app needs to support the same PHP version-range the supported Nextcloud version supports.
background-jobs/job
* optional
* must contain a php class which is run as background jobs
* will not be used, only validated
repair-steps/pre-migration/step
* optional
* must contain a php class which is run before executing database migrations
* will not be used, only validated
repair-steps/post-migration/step
* optional
* must contain a php class which is run after executing database migrations
* will not be used, only validated
repair-steps/live-migration/step
* optional
* must contain a php class which is run after executing post-migration jobs
* will not be used, only validated
repair-steps/install/step
* optional
* must contain a php class which is run after installing the app
* will not be used, only validated
repair-steps/uninstall/step
* optional
* must contain a php class which is run after uninstalling the app
* will not be used, only validated
two-factor-providers/provider
* optional
* must contain a php class which is registered as two factor auth provider
* will not be used, only validated
commands/command
* optional
* must contain a php class which is registered as occ command
* will not be used, only validated
activity/settings/setting
* optional
* must contain a php class which implements OCPActivityISetting and is used to add additional settings ui elements to the activity app
activity/filters/filter
* optional
* must contain a php class which implements OCPActivityIFilter and is used to add additional filters to the activity app
activity/providers/provider
* optional
* must contain a php class which implements OCPActivityIProvider and is used to react to events from the activity app
settings/admin
* optional
* must contain a php class which implements OCPSettingsISettings and returns the form to render for the global settings area
settings/admin-section
* optional
* must contain a php class which implements OCPSettingsISection and returns data to render navigation entries in the global settings area
navigations
* optional
* must contain at least one navigation element
navigations/navigation
* required
* must contain a name and route element
* denotes a navigation entry
* role denotes the visibility, all means everyone can see it, admin means only an admin can see the navigation entry, defaults to all
navigations/navigation/id
* optional
* the app id
* you can also create entries for other apps by setting an id other than your app one’s
navigations/navigation/name
* required
* will be displayed below the navigation entry icon
* will be translated by the default translation tools
navigations/navigation/route
* required
* name of the route that will be used to generate the link
navigations/navigation/icon
* optional
* name of the icon which is looked up in the app’s **img/** folder
* defaults to app.svg
navigations/navigation/order
* optional
* used to sort the navigation entries
* a higher order number means that the entry will be ordered further to the bottom
navigations/navigation/type
* optional
* can be either link or settings
* link means that the entry is added to the default app menu
* settings means that the entry is added to the right-side menu which also contains the personal, admin, users, help and logout entry
collaboration
* optional
* can contain plugins for collaboration search (e.g. supplying share dialog)
collaboration/plugins
* optional
* must contain at least one plugin
collaboration/plugins/plugin
* required
* the PHP class name of the plugin
* must contain **type** attribute (currently only _collaboration-search_). The class must implement OCPCollaborationCollaboratorsISearchPlugin.
* must contain **share-type** attribute, according to the specific OCPShare constants
The following character maximum lengths are enforced:
* All description Strings are database text fields and therefore not limited in size
* All other Strings have a maximum of 256 characters
The following elements are either deprecated or for internal use only and will fail the validation if present:
* **standalone**
* **default\_enable**
* **shipped**
* **public**
* **remote**
* **requiremin**
* **requiremax**
Changelog[](https://docs.nextcloud.com/server/32/developer_manual/app_development/info.html#changelog "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------
Apps can provide a changelog. This should be written in the [keep a changelog](https://keepachangelog.com/)
.
If the apps provide a `CHANGELOG.md` file in the project root, this file will be used to show changes for the released version in the app store and for administrators in the app settings.
Moreover, since Nextcloud 29, if the `updatenotification` app is enabled, apps can also provide a changelog for the users. The app will notify users about after the app update if either a `CHANGELOG.language.md` (where `language` is the language code of that user) or a fallback `CHANGELOG.en.md` is available.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# App metadata — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [App development](https://docs.nextcloud.com/server/stable/developer_manual/app_development/index.html)
* App metadata
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/app_development/info.rst)
* * *
App metadata[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html#app-metadata "Link to this heading")
=========================================================================================================================================
The `appinfo/info.xml` contains metadata about the app. A detailed documentation can be found at the [app store documentation](https://nextcloudappstore.readthedocs.io/en/latest/developer.html#info-xml)
.
The info.xml is validated using an XML Schema which can be accessed [online](https://apps.nextcloud.com/schema/apps/info.xsd)
.
A minimum valid **info.xml** would look like this:
appinfo/info.xml[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html#id2 "Link to this code")
newsNewsAn RSS/Atom feed readerAn RSS/Atom feed reader8.8.2AGPL-3.0-or-laterBernhard Posseltmultimediahttps://github.com/nextcloud/news/issues
A full blown example would look like this (needs to be utf-8 encoded):
appinfo/info.xml[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html#id3 "Link to this code")
newsNachrichtenNewsAn RSS/Atom feed reader# Description\\nAn RSS/Atom feed reader8.8.2AGPL-3.0-or-laterBernhard PosseltAlessandro CosentinoJan-Christoph Borchardthttps://github.com/nextcloud/news/wiki#user-documentationhttps://github.com/nextcloud/news#readmehttps://github.com/nextcloud/news/wiki#developer-documentationmultimediatoolshttps://github.com/nextcloud/newshttps://your.forum.comhttps://github.com/nextcloud/news/issueshttps://github.com/nextcloud/newshttps://example.com/1.pnghttps://example.com/2.jpgpgsqlsqlitemysqlgreplslibxmlcurlSimpleXMLiconvOCA\\DAV\\CardDAV\\Sync\\SyncJobOCA\\DAV\\Migration\\ClassificationOCA\\DAV\\Migration\\ClassificationOCA\\DAV\\Migration\\GenerateBirthdaysOCA\\DAV\\Migration\\GenerateBirthdaysOCA\\DAV\\Migration\\GenerateBirthdaysOCA\\AuthF\\TwoFactor\\ProviderA\\Php\\ClassOCA\\Theming\\Settings\\AdminOCA\\Theming\\Settings\\SectionOCA\\Files\\Activity\\Settings\\FavoriteActionOCA\\Files\\Activity\\Settings\\FileChangedOCA\\Files\\Activity\\Settings\\FileCreatedOCA\\Files\\Activity\\Settings\\FileDeletedOCA\\Files\\Activity\\Settings\\FileFavoriteOCA\\Files\\Activity\\Settings\\FileRestoredOCA\\Files\\Activity\\Filter\\FileChangesOCA\\Files\\Activity\\Filter\\FavoritesOCA\\Files\\Activity\\FavoriteProviderOCA\\Files\\Activity\\ProviderfilesFilesfiles.view.index0app.svglinkOCA\\Circles\\Collaboration\\v1\\CollaboratorSearchPlugin
The following tags are validated and used in the following way:
id
* required
* must contain only lowercase ASCII characters and underscore
* must match the first folder in the archive
* will be used to identify the app
name
* required
* must occur at least once with **lang=”en”** or no lang attribute
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app detail page
summary
* optional
* if not provided the description element’s text will be used
* must occur at least once with **lang=”en”** or no lang attribute
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app list page as short description
description
* required
* must occur at least once with **lang=”en”** or no lang attribute
* can contain Markdown
* can be translated by using multiple elements with different **lang** attribute values, language code needs to be set **lang** attribute
* will be rendered on the app detail page
version
* required
* must be a [semantic version](http://semver.org/)
without build metadata, e.g. 9.0.1 or 9.1.0-alpha.1
* [more info on app versioning](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/release_process.html#app-versioning)
licence
* required
* can occur multiple times with different licenses
* must contain one of the following licenses (for apps targeting v31 or higher, see the [SPDX License List](https://spdx.org/licenses/)
for details):
> * **AGPL-3.0-only**
>
> * **AGPL-3.0-or-later**
>
> * **Apache-2.0**
>
> * **GPL-3.0-only**
>
> * **GPL-3.0-or-later**
>
> * **MIT**
>
> * **MPL-2.0**
>
* (deprecated, for apps targeting v30 or lower) the following shorthand aliases are also used:
> * **agpl** (AGPL-3.0)
>
> * **apache** (Apache-2.0)
>
> * **gpl3** (GPL-3.0)
>
> * **mit** (MIT)
>
> * **mpl** (MPL-2.0)
>
author
* required
* can occur multiple times with different authors
* can contain a **mail** attribute which must be an email
* can contain a **homepage** which must be a URL
* will not (yet) be rendered on the App Store
* will be provided through the REST API
documentation/user
* optional
* must contain a URL to the user documentation
* will be rendered on the app detail page
documentation/admin
* optional
* must contain a URL to the admin documentation
* will be rendered on the app detail page
documentation/developer
* optional
* must contain a URL to the developer documentation
* will be rendered on the app detail page
category
* optional
* if not provided the category **tools** will be used
* must contain one of the following values:
> * **customization**
>
> * **files**
>
> * **games**
>
> * **integration**
>
> * **monitoring**
>
> * **multimedia**
>
> * **office**
>
> * **organization**
>
> * **security**
>
> * **social**
>
> * **tools**
>
* old categories are migrated:
> * **auth** will be converted to **security**
>
* can occur more than once with different categories
website
* optional
* must contain a URL to the project’s homepage
* will be rendered on the app detail page
discussion
* optional
* must contain a URL to the project’s discussion page/forum
* will be rendered on the app detail page as the “ask question or discuss” button
* if absent, it will default to our forum at [https://help.nextcloud.com/](https://help.nextcloud.com/)
bugs
* required
* must contain a URL to the project’s bug tracker
* will be rendered on the app detail page
repository
* optional
* must contain a URL to the project’s repository
* can contain a **type** attribute, **git**, **mercurial**, **subversion** and **bzr** are allowed values, defaults to **git**
* currently not used
screenshot
* optional
* must contain an HTTPS URL to an image
* can contain a **small-thumbnail** attribute which must contain an https url to an image. This image will be used as small preview (e.g. on the app list overview). Keep it small so it renders fast
* will be rendered on the app list and detail page in the given order
dependencies/php
* optional
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
* can contain a **min-int-size** attribute, 32 or 64 are allowed as valid values
* will be rendered on the app releases page
dependencies/database
* optional
* must contain the database name as text, **sqlite**, **pgsql** and **mysql** are allowed as valid values
* can occur multiple times with different databases
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
* will be rendered on the app releases page
dependencies/command
* optional
* must contain a linux command as text value
* can occur multiple times with different commands
* will be rendered on the app releases page
dependencies/lib
* optional
* will be rendered on the app releases page
* must contain a required php extension
* can occur multiple times with different php extensions
* can contain a **min-version** attribute (maximum 3 digits separated by dots)
* can contain a **max-version** attribute (maximum 3 digits separated by dots)
dependencies/nextcloud
* required
* must contain a **min-version** attribute (maximum 3 digits separated by dots)
* must contain a **max-version** attribute (maximum 3 digits separated by dots)
Note
Dependencies dependencies/php, dependencies/database and dependencies/lib are checked at installation time (not on update time), hence applications need to stick to the dependencies supported by a major version of Nextcloud the moment an app releases support for that version, i.e. app needs to support the same PHP version-range the supported Nextcloud version supports.
background-jobs/job
* optional
* must contain a php class which is run as background jobs
* will not be used, only validated
repair-steps/pre-migration/step
* optional
* must contain a php class which is run before executing database migrations
* will not be used, only validated
repair-steps/post-migration/step
* optional
* must contain a php class which is run after executing database migrations
* will not be used, only validated
repair-steps/live-migration/step
* optional
* must contain a php class which is run after executing post-migration jobs
* will not be used, only validated
repair-steps/install/step
* optional
* must contain a php class which is run after installing the app
* will not be used, only validated
repair-steps/uninstall/step
* optional
* must contain a php class which is run after uninstalling the app
* will not be used, only validated
two-factor-providers/provider
* optional
* must contain a php class which is registered as two factor auth provider
* will not be used, only validated
commands/command
* optional
* must contain a php class which is registered as occ command
* will not be used, only validated
activity/settings/setting
* optional
* must contain a php class which implements OCPActivityISetting and is used to add additional settings ui elements to the activity app
activity/filters/filter
* optional
* must contain a php class which implements OCPActivityIFilter and is used to add additional filters to the activity app
activity/providers/provider
* optional
* must contain a php class which implements OCPActivityIProvider and is used to react to events from the activity app
settings/admin
* optional
* must contain a php class which implements OCPSettingsISettings and returns the form to render for the global settings area
settings/admin-section
* optional
* must contain a php class which implements OCPSettingsISection and returns data to render navigation entries in the global settings area
navigations
* optional
* must contain at least one navigation element
navigations/navigation
* required
* must contain a name and route element
* denotes a navigation entry
* role denotes the visibility, all means everyone can see it, admin means only an admin can see the navigation entry, defaults to all
navigations/navigation/id
* optional
* the app id
* you can also create entries for other apps by setting an id other than your app one’s
navigations/navigation/name
* required
* will be displayed below the navigation entry icon
* will be translated by the default translation tools
navigations/navigation/route
* required
* name of the route that will be used to generate the link
navigations/navigation/icon
* optional
* name of the icon which is looked up in the app’s **img/** folder
* defaults to app.svg
navigations/navigation/order
* optional
* used to sort the navigation entries
* a higher order number means that the entry will be ordered further to the bottom
navigations/navigation/type
* optional
* can be either link or settings
* link means that the entry is added to the default app menu
* settings means that the entry is added to the right-side menu which also contains the personal, admin, users, help and logout entry
collaboration
* optional
* can contain plugins for collaboration search (e.g. supplying share dialog)
collaboration/plugins
* optional
* must contain at least one plugin
collaboration/plugins/plugin
* required
* the PHP class name of the plugin
* must contain **type** attribute (currently only _collaboration-search_). The class must implement OCPCollaborationCollaboratorsISearchPlugin.
* must contain **share-type** attribute, according to the specific OCPShare constants
The following character maximum lengths are enforced:
* All description Strings are database text fields and therefore not limited in size
* All other Strings have a maximum of 256 characters
The following elements are either deprecated or for internal use only and will fail the validation if present:
* **standalone**
* **default\_enable**
* **shipped**
* **public**
* **remote**
* **requiremin**
* **requiremax**
Changelog[](https://docs.nextcloud.com/server/stable/developer_manual/app_development/info.html#changelog "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------
Apps can provide a changelog. This should be written in the [keep a changelog](https://keepachangelog.com/)
.
If the apps provide a `CHANGELOG.md` file in the project root, this file will be used to show changes for the released version in the app store and for administrators in the app settings.
Moreover, since Nextcloud 29, if the `updatenotification` app is enabled, apps can also provide a changelog for the users. The app will notify users about after the app update if either a `CHANGELOG.language.md` (where `language` is the language code of that user) or a fallback `CHANGELOG.en.md` is available.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Front-end code — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/32/developer_manual/server/index.html)
* Front-end code
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/code-front-end.rst)
* * *
Front-end code[](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html#front-end-code "Link to this heading")
==========================================================================================================================================
Building Vue components and scripts[](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html#building-vue-components-and-scripts "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
We are moving more and more toward using Vue.js in the front-end, starting with Settings. For building the code on changes, use these terminal commands in the root folder:
\# install dependencies
npm install
\# build for development
npm run dev
\# build for development and watch edits
npm run watch
\# build for production with minification
npm run build
Building styles[](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html#building-styles "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------
Styles are written in SCSS and compiled to css.
\# install dependencies
make dev-setup
\# compile style sheets
npm run sass
\# compile style sheets and watch edits
npm run sass:watch
Committing changes[](https://docs.nextcloud.com/server/32/developer_manual/server/code-front-end.html#committing-changes "Link to this heading")
--------------------------------------------------------------------------------------------------------------------------------------------------
**When making changes, also commit the compiled files!**
We still use Handlebars templates in some places in Files and Settings. We will replace these step-by-step with Vue.js, but in the meantime, you need to compile them separately.
If you don’t have Handlebars installed yet, you can do it with this terminal command:
sudo npm install -g handlebars
Then inside the root folder of your local Nextcloud development installation, run this command in the terminal every time you changed a `.handlebars` file to compile it:
./build/compile-handlebars-templates.sh
Before checking in JS changes, make sure to also build for production:
make build-js-production
Then add the compiled files for committing.
To save some time, to only rebuild for a specific app, use the following and replace the module with the app name:
MODULE=user\_status make build-js-production
Please note that if you used `make build-js` or `make watch-js` before, you’ll notice that a lot of files were marked as changed, so might need to clear the workspace first.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Back-end code — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/stable/developer_manual/server/index.html)
* Back-end code
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/code-back-end.rst)
* * *
Back-end code[](https://docs.nextcloud.com/server/stable/developer_manual/server/code-back-end.html#back-end-code "Link to this heading")
===========================================================================================================================================
When changing back-end PHP code, in general, no additional steps are needed before checking in.
However, if new files were created, you will need to run the following command to update the autoloader files:
build/autoloaderchecker.sh
After that, please also include the autoloader file changes in your commits.
Compatibility documentation[](https://docs.nextcloud.com/server/stable/developer_manual/server/code-back-end.html#compatibility-documentation "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
* New APIs (interfaces, constants, methods, classes, traits, enums) added to the public namespace `OCP` have to be annotated with a `@since X.Y.Z` attribute of the version it was added in.
* When it is backported the version should be adjusted to the X.Y.Z of the stable version it was backported in only in that stable branch. The master branch should still contain the newest Major version shipping the API.
* Once an API was shipped, unless it is marked as experimental, it has to be deprecated in similar fashion using `@deprecated X.Y.Z` for 3 years (9 Nextcloud releases) before it can be removed. Deprecations have to be clearly documented in the [App upgrade guide](https://docs.nextcloud.com/server/stable/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html#app-upgrade-guide)
for the upcoming Major version.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Front-end code — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/stable/developer_manual/server/index.html)
* Front-end code
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/code-front-end.rst)
* * *
Front-end code[](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html#front-end-code "Link to this heading")
==============================================================================================================================================
Building Vue components and scripts[](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html#building-vue-components-and-scripts "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
We are moving more and more toward using Vue.js in the front-end, starting with Settings. For building the code on changes, use these terminal commands in the root folder:
\# install dependencies
npm install
\# build for development
npm run dev
\# build for development and watch edits
npm run watch
\# build for production with minification
npm run build
Building styles[](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html#building-styles "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------
Styles are written in SCSS and compiled to css.
\# install dependencies
make dev-setup
\# compile style sheets
npm run sass
\# compile style sheets and watch edits
npm run sass:watch
Committing changes[](https://docs.nextcloud.com/server/stable/developer_manual/server/code-front-end.html#committing-changes "Link to this heading")
------------------------------------------------------------------------------------------------------------------------------------------------------
**When making changes, also commit the compiled files!**
We still use Handlebars templates in some places in Files and Settings. We will replace these step-by-step with Vue.js, but in the meantime, you need to compile them separately.
If you don’t have Handlebars installed yet, you can do it with this terminal command:
sudo npm install -g handlebars
Then inside the root folder of your local Nextcloud development installation, run this command in the terminal every time you changed a `.handlebars` file to compile it:
./build/compile-handlebars-templates.sh
Before checking in JS changes, make sure to also build for production:
make build-js-production
Then add the compiled files for committing.
To save some time, to only rebuild for a specific app, use the following and replace the module with the app name:
MODULE=user\_status make build-js-production
Please note that if you used `make build-js` or `make watch-js` before, you’ll notice that a lot of files were marked as changed, so might need to clear the workspace first.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# How to test … — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/31/developer_manual/server/index.html)
* How to test …
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/how_to/index.rst)
* * *
How to test …[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#how-to-test "Link to this heading")
=============================================================================================================================
This page should explain how to test given features in Nextcloud.
Email sending[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#email-sending "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------
docker run \-d \-p 1025:1025 \-p 8025:8025 mailhog/mailhog
occ config:system:set mail\_smtpmode \--value\=smtp
occ config:system:set mail\_smtphost \--value\=127.0.0.1
occ config:system:set mail\_smtpport \--value\=1025 \--type\=integer
Then after having Nextcloud send some emails, open [http://127.0.0.1:8025](http://127.0.0.1:8025/)
to view them.
Redis[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#redis "Link to this heading")
---------------------------------------------------------------------------------------------------------------
First you need to install the [phpredis extension](https://github.com/phpredis/phpredis)
. There is a install document available [inside the repo](https://github.com/phpredis/phpredis/blob/develop/INSTALL.markdown)
and many linux distribtutions ship it in their repositories as well.
> pecl install redis
Redis Cluster[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#redis-cluster "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------
For a local Redis cluster setup there are some docker script collected in [this repository](https://github.com/Grokzen/docker-redis-cluster)
. It boils down to clone the repo and run make up. Then the redis cluster is available at `localhost:7000`.
Following `config.php` can be used:
'memcache.distributed' \=> '\\OC\\Memcache\\Redis',
'redis.cluster' \=> \[\
'seeds' \=> \[ // provide some/all of the cluster servers to bootstrap discovery, port required\
'localhost:7000',\
\],\
'timeout' \=> 0.0,\
'read\_timeout' \=> 0.0,\
'failover\_mode' \=> \\RedisCluster::FAILOVER\_ERROR,\
\],
Primary object store with S3[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#primary-object-store-with-s3 "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
docker run \-p 9000:9000 minio/minio server /data
The edit `config.php` and add the following section:
'objectstore' \=>
array (
'class' \=> 'OC\\\\Files\\\\ObjectStore\\\\S3',
'arguments' \=>
array (
'bucket' \=> 'nextcloud-dev',
'key' \=> 'minioadmin',
'secret' \=> 'minioadmin',
'hostname' \=> 'localhost',
'port' \=> '9000',
'use\_ssl' \=> false,
'use\_path\_style' \=> true,
),
),
S3 external storage[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#s3-external-storage "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------
occ app:enable files\_external
docker run \-p 9000:9000 minio/minio server /data
Then add an external storage in the web UI using the following configuration:
* Authentication type: Access key
* Access key: minioadmin
* Secret key: minioadmin
* Bucket: nextcloud-dev
* Hostname: localhost
* Port: 9000
* Region: leave empty
* Storage class: leave empty
* Enable SSL: false
* Enable path style: yes
SMB external storage[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#smb-external-storage "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------
SMB external storage can be tested with Docker. The following commands create an SMB server with a public (shared) directory and user home directories for the credentials `smb1:pwd1` and `smb2:pwd2`.
occ app:enable files\_external
mkdir \-p /tmp/samba/{public,home/{smb1,smb2}}
chmod a+rw /tmp/samba/home/smb\*
docker run \-it \-p 139:139 \-p 445:445 \\
\-v /tmp/samba/public:/smbpublic \\
\-v /tmp/samba/home:/smbhome \\
dperson/samba \\
\-u "smb1;pwd1" \\
\-u "smb2;pwd2" \\
\-s "public;/smbmount;yes;no;yes" \\
\-s "home;/smbhome/%U;yes;no;no;all;none"
Make sure that smbclient is installed on your Nextcloud server and has the following configuration:
\# /etc/samba/smb.conf
\[global\]
client min protocol \= SMB2
client max protocol \= SMB3
hide dot files \= no
The setup can be verified with
smbclient //127.0.0.1/public \-U smb1 \# Shared storage for all users
smbclient //127.0.0.1/home \-U smb1 \--password\=pwd1 \# Home storage
SAML setup with onelogin[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#saml-setup-with-onelogin "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------
* create dev account on onelogin.com
* log into onelogin.com
* create new app: SAML Test Connector (Advanced)
> * go to “Configuration”
>
> > * Audience: [https://localhost/apps/user\_saml/saml/metadata](https://localhost/apps/user_saml/saml/metadata)
> >
> > * Recipient: [https://localhost/apps/user\_saml/saml/acs](https://localhost/apps/user_saml/saml/acs)
> >
> > * ACS (Consumer) URL Validator: [https://localhost/apps/user\_saml/saml/acs](https://localhost/apps/user_saml/saml/acs)
> >
>
> * go to “Parameters”
>
> > * Add “User.email” -> email (and add to assertion)
> >
> > * Add “User.FirstName” -> first name (and add to assertion)
> >
> > * Add “User.LastName” -> last name (and add to assertion)
> >
>
* open Nextcloud SAML settings
> * Select SAML
>
> * Configure it according to [https://portal.nextcloud.com/article/configuring-single-sign-on-10.html](https://portal.nextcloud.com/article/configuring-single-sign-on-10.html)
>
Collabora without SSL[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#collabora-without-ssl "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------
**1) Start Collabora in a docker container**
docker run \-p 127.0.0.1:9980:9980 \-e 'domain=172.17.0.1' \\
\-e 'username=admin' \-e 'password=487903ffcf4' \\
\-e extra\_params\='--o:ssl.enable=false' \\
\--restart always \--cap\-add MKNOD collabora/code
* 172.17.0.1 is localhost, which is default by Docker
* get IP of Collabora container: docker inspect –format=’{{ .NetworkSettings.IPAddress }}’ $containerName
**2) Configure Nextcloud**
* go to your local cloud (e.g. 172.17.0.1/nc) -> Settings -> Collabora
* set URL to IP you found out above, e.g: [http://172.17.0.2:9980](http://172.17.0.2:9980/)
* check “Disable certificate verification (insecure)
**3) Use**
* please note that you cannot use it with localhost, but you have to enter a valid IP address of localhost
* with this approach you can also use it with mobile clients
**4) Troubleshoot**
* [http://172.17.0.2:9980/hosting/capabilities](http://172.17.0.2:9980/hosting/capabilities)
should give you:
{"convert-to":{"available":false},"hasMobileSupport":true,"hasTemplateSaveAs":true,"productName":"Collabora Online Development Edition"}
OnlyOffice[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#onlyoffice "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------
1. Create self signed cert, should be on a permanent path:
mkdir \-p /tmp/oo/certs
cd /tmp/oo/certs
openssl genrsa \-out onlyoffice.key 4096
openssl req \-new \-key onlyoffice.key \-out onlyoffice.csr
openssl x509 \-req \-days 3650 \-in onlyoffice.csr \-signkey onlyoffice.key \-out onlyoffice.crt
openssl dhparam \-out dhparam.pem 4096
chmod 400 onlyoffice.key
chmod 400 onlyoffice.crt
chmod 400 onlyoffice.csr
chmod 400 dhparam.pem
2. Start docker, important: do not use certs folder, but parent folder:
docker run \--name\=ONLYOFFICEDOCKER \-i \-t \-d \-p 4433:443 \\
\-e JWT\_ENABLED\='true' \-e JWT\_SECRET\='secret' \--restart\=always \\
\-v /tmp/oo/:/var/www/onlyoffice/Data onlyoffice/documentserver
3. Go into docker container:
> * docker exec -it ONLYOFFICEDOCKER /bin/bash
>
> * apt-get update
>
> * apt-get install vim -y
>
> * vim /etc/onlyoffice/documentserver/default.json
>
> * change rejectUnauthorized to false
>
>
> * vim /etc/onlyoffice/documentserver/local.json
>
> * change token -> inbox -> header to “AuthorizationJWT”
>
> * change token -> outbox -> header to “AuthorizationJWT”
>
>
> * Add the following to your config.php
>
>
> 'onlyoffice' \=> array (
> 'verify\_peer\_off' \=> true,
> 'jwt\_secret' \=> 'secret',
> 'jwt\_header' \=> 'AuthorizationJWT'
> ),
Test with local ip: [https://localhost:4433](https://localhost:4433/)
* accept cert warning
* verify that “Document Server is running” is shown
Test with Nextcloud
* download & enable OnlyOffice app
* configure:
* Document Editing Service address: [https://localhost:4433/](https://localhost:4433/)
* Secret key : secret (as above)
* Document Editing Service address for internal requests from the server: [https://localhost:4433/](https://localhost:4433/)
* Server address for internal requests from the Document Editing Service: [http://192.168.1.95/nc16/](http://192.168.1.95/nc16/)
(needs to be real IP address, as localhost points to docker)
WebAuthn without SSL[](https://docs.nextcloud.com/server/31/developer_manual/how_to/index.html#webauthn-without-ssl "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------
[Chrome has the option to test WebAuthn with a fake device](https://developer.chrome.com/docs/devtools/webauthn/)
. Browsers support WebAuthn on HTTPS protected sites and localhost domains. Unfortunately this is not supported by the used PHP library where the check for HTTPS needs to be commented for testing on non-HTTPS localhost development environments.
diff --git a/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php b/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php
index 8400ba9c..49279cc7 100644
--- a/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php
+++ b/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAssertionResponseValidator.php
@@ -152,7 +152,7 @@ class AuthenticatorAssertionResponseValidator
Assertion::isArray($parsedRelyingPartyId, 'Invalid origin');
if (!in\_array($facetId, $securedRelyingPartyId, true)) {
$scheme = $parsedRelyingPartyId\['scheme'\] ?? '';
- Assertion::eq('https', $scheme, 'Invalid scheme. HTTPS required.');
+ #Assertion::eq('https', $scheme, 'Invalid scheme. HTTPS required.');
}
$clientDataRpId = $parsedRelyingPartyId\['host'\] ?? '';
Assertion::notEmpty($clientDataRpId, 'Invalid origin rpId.');
diff --git a/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php b/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php
index f3e5a15d..3927bf23 100644
--- a/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php
+++ b/3rdparty/web-auth/webauthn-lib/src/AuthenticatorAttestationResponseValidator.php
@@ -150,7 +150,7 @@ class AuthenticatorAttestationResponseValidator
if (!in\_array($facetId, $securedRelyingPartyId, true)) {
$scheme = $parsedRelyingPartyId\['scheme'\] ?? '';
- Assertion::eq('https', $scheme, 'Invalid scheme. HTTPS required.');
+ #Assertion::eq('https', $scheme, 'Invalid scheme. HTTPS required.');
}
/\* @see 7.1.6 \*/
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Static analysis — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/32/developer_manual/server/index.html)
* Static analysis
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/static-analysis.rst)
* * *
Static analysis[](https://docs.nextcloud.com/server/32/developer_manual/server/static-analysis.html#static-analysis "Link to this heading")
=============================================================================================================================================
PHP static analysis[](https://docs.nextcloud.com/server/32/developer_manual/server/static-analysis.html#php-static-analysis "Link to this heading")
-----------------------------------------------------------------------------------------------------------------------------------------------------
In the server repository psalm is used for static analysis of the PHP code.
### Required PHP extensions[](https://docs.nextcloud.com/server/32/developer_manual/server/static-analysis.html#required-php-extensions "Link to this heading")
The following PHP extensions are required to be installed and enabled to make psalm work:
* acpu
* curl
* ftp
* gd
* iconv
* imagick
* json
* ldap
* libxml
* mbstring
* openssl
* pdo
* simplexml
* sysvsem
* xmlreader
* zip
Some of these are for optional features, but are still required to validate the code.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Static analysis — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/stable/developer_manual/server/index.html)
* Static analysis
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/static-analysis.rst)
* * *
Static analysis[](https://docs.nextcloud.com/server/stable/developer_manual/server/static-analysis.html#static-analysis "Link to this heading")
=================================================================================================================================================
PHP static analysis[](https://docs.nextcloud.com/server/stable/developer_manual/server/static-analysis.html#php-static-analysis "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------------------------------
In the server repository psalm is used for static analysis of the PHP code.
### Required PHP extensions[](https://docs.nextcloud.com/server/stable/developer_manual/server/static-analysis.html#required-php-extensions "Link to this heading")
The following PHP extensions are required to be installed and enabled to make psalm work:
* acpu
* curl
* ftp
* gd
* iconv
* imagick
* json
* ldap
* libxml
* mbstring
* openssl
* pdo
* simplexml
* sysvsem
* xmlreader
* zip
Some of these are for optional features, but are still required to validate the code.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Back-end code — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/32/developer_manual/index.html)
* [Server development](https://docs.nextcloud.com/server/32/developer_manual/server/index.html)
* Back-end code
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/server/code-back-end.rst)
* * *
Back-end code[](https://docs.nextcloud.com/server/32/developer_manual/server/code-back-end.html#back-end-code "Link to this heading")
=======================================================================================================================================
When changing back-end PHP code, in general, no additional steps are needed before checking in.
However, if new files were created, you will need to run the following command to update the autoloader files:
build/autoloaderchecker.sh
After that, please also include the autoloader file changes in your commits.
Compatibility documentation[](https://docs.nextcloud.com/server/32/developer_manual/server/code-back-end.html#compatibility-documentation "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------------
* New APIs (interfaces, constants, methods, classes, traits, enums) added to the public namespace `OCP` have to be annotated with a `@since X.Y.Z` attribute of the version it was added in.
* When it is backported the version should be adjusted to the X.Y.Z of the stable version it was backported in only in that stable branch. The master branch should still contain the newest Major version shipping the API.
* Once an API was shipped, unless it is marked as experimental, it has to be deprecated in similar fashion using `@deprecated X.Y.Z` for 3 years (9 Nextcloud releases) before it can be removed. Deprecations have to be clearly documented in the [App upgrade guide](https://docs.nextcloud.com/server/32/developer_manual/app_publishing_maintenance/app_upgrade_guide/index.html#app-upgrade-guide)
for the upcoming Major version.
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[31](https://docs.nextcloud.com/server/31/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
---
# Events — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/31/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/31/developer_manual/basics/index.html)
* Events
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/events.rst)
* * *
Events[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#events "Link to this heading")
==================================================================================================================
Events are used to communicate between different aspects of the Nextcloud eco system. They are used in the Nextcloud server internally, for server-to-apps communication as well as inter-app communication.
Overview[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#overview "Link to this heading")
----------------------------------------------------------------------------------------------------------------------
The term “events” is a bit broad in Nextcloud and there are multiple ways of emitting them.
* [OCP event dispatcher](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-event-dispatcher)
* [Hooks](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#hooks)
* [Public Emitter](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#public-emitter)
OCP event dispatcher[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-event-dispatcher "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------------------
This mechanism is a versatile and typed approach to events in Nextcloud’s php code. It uses objects rather than just passing primitives or untyped arrays. This should help provide a better developer experience while lowering the risk of unexpected changes in the API that are hard to find after the initial implementation.
### Naming scheme[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#naming-scheme "Link to this heading")
The name should reflect the subject and the actions. Suffixing event classes with Event makes it easier to recognize their purpose.
For example, if a user is created, a UserCreatedEvent will be emitted.
Events are usually emitted _after_ the event has happened. If it’s emitted before, it should be prefixed with Before.
Thus BeforeUserCreatedEvent is emitted _before_ the user data is written to the database.
Note
Although you may choose to name your event classes differently, sticking to the convention will allow Nextcloud developers understand each other’s apps more easily.
Note
For backwards compatibility with the Symfony class [GenericEvent](https://symfony.com/doc/current/components/event_dispatcher/generic_event.html)
, Nextcloud also provides a `\OCP\EventDispatcher\Event` class. With the release of Nextcloud 22 this class has been deprecated. Named and typed event classes should be used instead.
### Writing events[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#writing-events "Link to this heading")
As a rule events are dedicated classes extending `\OCP\EventDispatcher\Event`.
user \= $user;
}
public function getUser(): IUser {
return $this\->user;
}
}
### Writing a listener[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#writing-a-listener "Link to this heading")
A listener can be a simple callback function (or anything else that is [callable](https://www.php.net/manual/en/language.types.callable.php)
, or a dedicated class.
#### Listener callbacks[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#listener-callbacks "Link to this heading")
You can use simple callback to react on events. They will receive the event object as first and only parameter. You can type-hint the base Event class or the subclass you expect and register for.
getContainer()\->query(IEventDispatcher::class);
$dispatcher\->addListener(AddEvent::class, function(AddEvent $event) {
// ...
});
}
}
Note
Type-hinting the actual event class will give you better IDE and static analyzers support. It’s generally safe to assume the dispatcher will not give you any other objects.
#### Listener classes[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#listener-classes "Link to this heading")
A class that can handle an event will implement the `\OCP\EventDispatcher\IEventListener` interface. Class names should end with Listener.
addToCounter(2);
}
}
Note
Php parameter type hints are not allowed to be more specific than the type hints on the interface, thus you can’t use AddEvent in the method signature but use an instanceOf instead.
In the `Application.php` the event and the listener class are connected. The class is instantiated only when the actual event is fired.
getContainer()\->get(IEventDispatcher::class);
$dispatcher\->addServiceListener(AddEvent::class, AddTwoListener::class);
}
}
Note
The listener is resolved via the DI container, therefore you can add a constructor and type-hint services required for processing the event.
### Available Events[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#available-events "Link to this heading")
Here you find an overview of the public events that can be consumed in apps. See their source files for more details.
#### `\OCA\DAV\Events\AddressBookCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-addressbookcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new address-book.
#### `\OCA\DAV\Events\AddressBookDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-addressbookdeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes an address-book.
#### `\OCA\DAV\Events\AddressBookShareUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-addressbookshareupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user shares or unshares an address-book.
#### `\OCA\DAV\Events\AddressBookUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-addressbookupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates an address-book.
#### `\OCA\DAV\Events\CachedCalendarObjectCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-cachedcalendarobjectcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a cached calendar object is being created while fetching a calendar-subscription.
#### `\OCA\DAV\Events\CachedCalendarObjectDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-cachedcalendarobjectdeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a cached calendar object is being deleted while fetching a calendar-subscription.
#### `\OCA\DAV\Events\CachedCalendarObjectUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-cachedcalendarobjectupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a cached calendar object is being updated while fetching a calendar-subscription.
#### `\OCA\DAV\Events\CalendarCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new calendar.
#### `\OCA\DAV\Events\CalendarDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendardeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar.
#### `\OCA\DAV\Events\CalendarObjectCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarobjectcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a calendar-object.
#### `\OCA\DAV\Events\CalendarObjectDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarobjectdeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar-object.
#### `\OCA\DAV\Events\CalendarObjectUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarobjectupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates a calendar-object.
#### `\OCA\DAV\Events\CalendarPublishedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarpublishedevent "Link to this heading")
Added in version 20.
This event is triggered when a user publishes a calendar.
#### `\OCA\DAV\Events\CalendarShareUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarshareupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user shares or unshares a calendar.
#### `\OCA\DAV\Events\CalendarUnpublishedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarunpublishedevent "Link to this heading")
Added in version 20.
This event is triggered when a user unpublishes calendar.
#### `\OCA\DAV\Events\CalendarUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-calendarupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates a calendar.
#### `\OCA\DAV\Events\CardCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-cardcreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new card in an address-book.
#### `\OCA\DAV\Events\CardDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-carddeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a card in an address-book.
#### `\OCA\DAV\Events\CardUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-cardupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user updates a card in an address-book.
#### `OCA\DAV\Events\SabrePluginAddEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-sabrepluginaddevent "Link to this heading")
Added in version 28.
This event is triggered during the setup of the SabreDAV server to allow the registration of additional plugins.
#### `\OCA\DAV\Events\SabrePluginAuthInitEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-sabrepluginauthinitevent "Link to this heading")
Added in version 20.
This event is triggered during the setup of the SabreDAV server to allow the registration of additional authentication backends.
#### `\OCA\DAV\Events\SubscriptionCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-subscriptioncreatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user creates a new calendar-subscription.
#### `\OCA\DAV\Events\SubscriptionDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-subscriptiondeletedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar-subscription.
#### `\OCA\DAV\Events\SubscriptionUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-dav-events-subscriptionupdatedevent "Link to this heading")
Added in version 20.
This event is triggered when a user deletes a calendar-subscription.
#### `\OCA\FederatedFileSharing\Events\FederatedShareAddedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-federatedfilesharing-events-federatedshareaddedevent "Link to this heading")
Added in version 20.
This event is triggered when a federated share is successfully added.
#### `\OCA\Files\Event\LoadAdditionalScriptsEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-files-event-loadadditionalscriptsevent "Link to this heading")
Added in version 17.
This event is triggered when the files app is rendered. It can be used to add additional scripts to the files app.
#### `\OCA\Files_Sharing\Event\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-files-sharing-event-beforetemplaterenderedevent "Link to this heading")
Added in version 20.
Emitted before the rendering step of the public share page happens. The event holds a flag that specifies if it is the authentication page of a public share.
#### `\OCA\Files_Trashbin\Events\MoveToTrashEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-files-trashbin-events-movetotrashevent "Link to this heading")
Added in version 28.
Emitted after a file or folder is moved to the trashbin.
#### `\OCA\Settings\Events\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-settings-events-beforetemplaterenderedevent "Link to this heading")
Added in version 20.
This event is triggered right before the user management template is rendered.
#### `\OCA\User_LDAP\Events\GroupBackendRegistered`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-user-ldap-events-groupbackendregistered "Link to this heading")
Added in version 20.
This event is triggered right after the LDAP group backend is registered.
#### `\OCA\User_LDAP\Events\UserBackendRegistered`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-user-ldap-events-userbackendregistered "Link to this heading")
Added in version 20.
This event is triggered right after the LDAP user backend is registered.
#### `\OCA\Viewer\Event\LoadViewer`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#oca-viewer-event-loadviewer "Link to this heading")
Added in version 17.
This event is triggered whenever the viewer is loaded and extensions should be loaded.
#### `OCP\Accounts\UserUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-accounts-userupdatedevent "Link to this heading")
Added in version 28.
This event is triggered when the account data of a user was updated.
#### `OCP\App\Events\AppDisableEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-app-events-appdisableevent "Link to this heading")
Added in version 27.
This event is triggered when an app is disabled.
#### `OCP\App\Events\AppEnableEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-app-events-appenableevent "Link to this heading")
Added in version 27.
This event is triggered when an app is enabled.
#### `OCP\App\Events\AppUpdateEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-app-events-appupdateevent "Link to this heading")
Added in version 27.
This event is triggered when an app is updated.
#### `OCP\App\ManagerEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-app-managerevent "Link to this heading")
Added in version 9.
Class ManagerEvent
#### `OCP\AppFramework\Http\Events\BeforeLoginTemplateRenderedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-appframework-http-events-beforelogintemplaterenderedevent "Link to this heading")
Added in version 28.
Emitted before the rendering step of the login TemplateResponse.
#### `OCP\AppFramework\Http\Events\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-appframework-http-events-beforetemplaterenderedevent "Link to this heading")
Added in version 20.
Emitted before the rendering step of each TemplateResponse. The event holds a flag that specifies if an user is logged in.
#### `OCP\Authentication\Events\AnyLoginFailedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-events-anyloginfailedevent "Link to this heading")
Added in version 26.
Emitted when the authentication fails
#### `OCP\Authentication\Events\LoginFailedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-events-loginfailedevent "Link to this heading")
Added in version 19.
Emitted when the authentication fails, but only if the login name can be associated with an existing user.
#### `OCP\Authentication\TwoFactorAuth\RegistryEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-registryevent "Link to this heading")
Added in version 15.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengeFailed`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderchallengefailed "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderChallengePassed`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderchallengepassed "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderDisabled`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderdisabled "Link to this heading")
Added in version 20.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserDisabled`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserdisabled "Link to this heading")
Added in version 22.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserEnabled`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserenabled "Link to this heading")
Added in version 22.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserRegistered`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserregistered "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderForUserUnregistered`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorproviderforuserunregistered "Link to this heading")
Added in version 28.
#### `OCP\Authentication\TwoFactorAuth\TwoFactorProviderUserDeleted`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-authentication-twofactorauth-twofactorprovideruserdeleted "Link to this heading")
Added in version 28.
#### `OCP\BeforeSabrePubliclyLoadedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-beforesabrepubliclyloadedevent "Link to this heading")
Added in version 26.
Dispatched before Sabre is loaded when accessing public webdav endpoints This can be used to inject a Sabre plugin for example
#### `OCP\Collaboration\AutoComplete\AutoCompleteEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-collaboration-autocomplete-autocompleteevent "Link to this heading")
Added in version 16.
#### `OCP\Collaboration\AutoComplete\AutoCompleteFilterEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-collaboration-autocomplete-autocompletefilterevent "Link to this heading")
Added in version 28.
#### `OCP\Collaboration\Reference\RenderReferenceEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-collaboration-reference-renderreferenceevent "Link to this heading")
Added in version 25.
Event emitted when apps might render references like link previews or smart picker widgets. This can be used to inject scripts for extending that. Further details can be found in the [Reference providers](https://docs.nextcloud.com/server/31/developer_manual/digging_deeper/reference.html#reference-providers)
deep dive.
#### `OCP\Collaboration\Resources\LoadAdditionalScriptsEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-collaboration-resources-loadadditionalscriptsevent "Link to this heading")
Added in version 25.
This event is used by apps to register their own frontend scripts for integrating projects in their app. Apps also need to dispatch the event in order to load scripts during page load
#### `OCP\Comments\CommentsEntityEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-comments-commentsentityevent "Link to this heading")
Added in version 9.1.
Changed in version 28.0.0: Dispatched as a typed event
Class CommentsEntityEvent
#### `OCP\Comments\CommentsEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-comments-commentsevent "Link to this heading")
Added in version 9.
Class CommentsEvent
#### `OCP\Config\BeforePreferenceDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-config-beforepreferencedeletedevent "Link to this heading")
Added in version 25.
#### `OCP\Config\BeforePreferenceSetEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-config-beforepreferencesetevent "Link to this heading")
Added in version 25.
#### `OCP\Console\ConsoleEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-console-consoleevent "Link to this heading")
Added in version 9.
Class ConsoleEvent
#### `OCP\Contacts\Events\ContactInteractedWithEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-contacts-events-contactinteractedwithevent "Link to this heading")
Added in version 19.
An event that allows apps to notify other components about an interaction between two users. This can be used to build better recommendations and suggestions in user interfaces. Emitters should add at least one identifier (uid, email, federated cloud ID) of the recipient of the interaction.
#### `OCP\DB\Events\AddMissingColumnsEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-db-events-addmissingcolumnsevent "Link to this heading")
Added in version 28.
Event to allow apps to register information about missing database columns This event will be dispatched for checking on the admin settings and when running occ db:add-missing-columns which will then create those columns
#### `OCP\DB\Events\AddMissingIndicesEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-db-events-addmissingindicesevent "Link to this heading")
Added in version 28.
Event to allow apps to register information about missing database indices This event will be dispatched for checking on the admin settings and when running occ db:add-missing-indices which will then create those indices
#### `OCP\DB\Events\AddMissingPrimaryKeyEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-db-events-addmissingprimarykeyevent "Link to this heading")
Added in version 28.
Event to allow apps to register information about missing database primary keys This event will be dispatched for checking on the admin settings and when running occ db:add-missing-primary-keys which will then create those keys
#### `OCP\DirectEditing\RegisterDirectEditorEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-directediting-registerdirecteditorevent "Link to this heading")
Added in version 18.
Event to allow to register the direct editor.
#### `OCP\EventDispatcher\GenericEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-eventdispatcher-genericevent "Link to this heading")
Added in version 18.
Class GenericEvent convenience reimplementation of SymfonyComponentGenericEvent against OCPEventDispatcherEvent
#### `OCP\Federation\Events\TrustedServerRemovedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-federation-events-trustedserverremovedevent "Link to this heading")
Added in version 25.
#### `OCP\Files\Cache\AbstractCacheEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-cache-abstractcacheevent "Link to this heading")
Added in version 22.
#### `OCP\Files\Cache\CacheEntryInsertedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-cache-cacheentryinsertedevent "Link to this heading")
Added in version 21.
Event for when an existing entry in the cache gets inserted
#### `OCP\Files\Cache\CacheEntryRemovedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-cache-cacheentryremovedevent "Link to this heading")
Added in version 21.
Event for when an existing entry in the cache gets removed
#### `OCP\Files\Cache\CacheEntryUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-cache-cacheentryupdatedevent "Link to this heading")
Added in version 21.
Event for when an existing entry in the cache gets updated
#### `OCP\Files\Cache\CacheInsertEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-cache-cacheinsertevent "Link to this heading")
Added in version 16.
Event for when a new entry gets added to the cache
#### `OCP\Files\Cache\CacheUpdateEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-cache-cacheupdateevent "Link to this heading")
Added in version 16.
Event for when an existing entry in the cache gets updated
#### `OCP\Files\Events\BeforeDirectFileDownloadEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-beforedirectfiledownloadevent "Link to this heading")
Added in version 25.
This event is triggered when a user tries to download a file directly.
#### `OCP\Files\Events\BeforeFileScannedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-beforefilescannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\BeforeFolderScannedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-beforefolderscannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\BeforeZipCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-beforezipcreatedevent "Link to this heading")
Added in version 25.
#### `OCP\Files\Events\FileCacheUpdated`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-filecacheupdated "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\FileScannedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-filescannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\FolderScannedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-folderscannedevent "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\InvalidateMountCacheEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-invalidatemountcacheevent "Link to this heading")
Added in version 24.
Used to notify the filesystem setup manager that the available mounts for a user have changed
#### `OCP\Files\Events\Node\BeforeNodeCopiedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-beforenodecopiedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-beforenodecreatedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-beforenodedeletedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeReadEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-beforenodereadevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeRenamedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-beforenoderenamedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeTouchedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-beforenodetouchedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\BeforeNodeWrittenEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-beforenodewrittenevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\FilesystemTornDownEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-filesystemtorndownevent "Link to this heading")
Added in version 24.
Event fired after the filesystem has been torn down
#### `OCP\Files\Events\Node\NodeCopiedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-nodecopiedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-nodecreatedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-nodedeletedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeRenamedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-noderenamedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeTouchedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-nodetouchedevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\Node\NodeWrittenEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-node-nodewrittenevent "Link to this heading")
Added in version 20.
#### `OCP\Files\Events\NodeAddedToCache`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-nodeaddedtocache "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\NodeAddedToFavorite`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-nodeaddedtofavorite "Link to this heading")
Added in version 28.
#### `OCP\Files\Events\NodeRemovedFromCache`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-noderemovedfromcache "Link to this heading")
Added in version 18.
#### `OCP\Files\Events\NodeRemovedFromFavorite`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-events-noderemovedfromfavorite "Link to this heading")
Added in version 28.
#### `OCP\Files\Template\BeforeGetTemplatesEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-template-beforegettemplatesevent "Link to this heading")
Added in version 30.
#### `OCP\Files\Template\FileCreatedFromTemplateEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-template-filecreatedfromtemplateevent "Link to this heading")
Added in version 21.
#### `OCP\Files\Template\RegisterTemplateCreatorEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-files-template-registertemplatecreatorevent "Link to this heading")
Added in version 30.
#### `OCP\FilesMetadata\Event\MetadataBackgroundEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-filesmetadata-event-metadatabackgroundevent "Link to this heading")
Added in version 28.
MetadataBackgroundEvent is an event similar to MetadataLiveEvent but dispatched on a background thread instead of live thread. Meaning there is no limit to the time required for the generation of your metadata.
#### `OCP\FilesMetadata\Event\MetadataLiveEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-filesmetadata-event-metadataliveevent "Link to this heading")
Added in version 28.
MetadataLiveEvent is an event initiated when a file is created or updated. The app contains the Node related to the created/updated file, and a FilesMetadata that already contains the currently known metadata.
Setting new metadata, or modifying already existing metadata with different value, will trigger the save of the metadata in the database.
#### `OCP\FilesMetadata\Event\MetadataNamedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-filesmetadata-event-metadatanamedevent "Link to this heading")
Added in version 28.
MetadataNamedEvent is an event similar to MetadataBackgroundEvent completed with a target name, used to limit the refresh of metadata only listeners capable of filtering themselves out. Meaning that when using this event, your app must implement a filter on the event’s registered name returned by getName()
This event is mostly triggered when a registered name is added to the files scan
i.e. ./occ files:scan –generate-metadata \[name\]
#### `OCP\Group\Events\BeforeGroupChangedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-beforegroupchangedevent "Link to this heading")
Added in version 26.
#### `OCP\Group\Events\BeforeGroupCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-beforegroupcreatedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\BeforeGroupDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-beforegroupdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\BeforeUserAddedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-beforeuseraddedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\BeforeUserRemovedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-beforeuserremovedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\GroupChangedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-groupchangedevent "Link to this heading")
Added in version 26.
#### `OCP\Group\Events\GroupCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-groupcreatedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\GroupDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-groupdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\SubAdminAddedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-subadminaddedevent "Link to this heading")
Added in version 21.
#### `OCP\Group\Events\SubAdminRemovedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-subadminremovedevent "Link to this heading")
Added in version 21.
#### `OCP\Group\Events\UserAddedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-useraddedevent "Link to this heading")
Added in version 18.
#### `OCP\Group\Events\UserRemovedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-group-events-userremovedevent "Link to this heading")
Added in version 18.
#### `OCP\Log\Audit\CriticalActionPerformedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-log-audit-criticalactionperformedevent "Link to this heading")
Added in version 22.
Emitted when the admin\_audit app should log an entry
#### `OCP\Log\BeforeMessageLoggedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-log-beforemessageloggedevent "Link to this heading")
Added in version 28.
Even for when a log item is being logged
#### `OCP\Mail\Events\BeforeMessageSent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-mail-events-beforemessagesent "Link to this heading")
Added in version 19.
Emitted before a system mail is sent. It can be used to alter the message.
#### `OCP\OCM\Events\ResourceTypeRegisterEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-ocm-events-resourcetyperegisterevent "Link to this heading")
Added in version 28.
Use this event to register additional OCM resources before the API returns them in the OCM provider list and capability
#### `OCP\Preview\BeforePreviewFetchedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-preview-beforepreviewfetchedevent "Link to this heading")
Added in version 25.0.1.
Changed in version 28.0.0: the constructor arguments `$width`, `$height`, `$crop` and `$mode` are no longer nullable.
Emitted before a file preview is being fetched. It can be used to block preview rendering by throwing a `OCP\Files\NotFoundException`
#### `OCP\Profile\BeforeTemplateRenderedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-profile-beforetemplaterenderedevent "Link to this heading")
Added in version 25.
Emitted before the rendering step of the public profile page happens.
#### `OCP\SabrePluginEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-sabrepluginevent "Link to this heading")
Added in version 8.2.
#### `OCP\Security\CSP\AddContentSecurityPolicyEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-security-csp-addcontentsecuritypolicyevent "Link to this heading")
Added in version 17.
Allows to inject something into the default content policy. This is for example useful when you’re injecting Javascript code into a view belonging to another controller and cannot modify its Content-Security-Policy itself. Note that the adjustment is only applied to applications that use AppFramework controllers.
WARNING: Using this API incorrectly may make the instance more insecure. Do think twice before adding whitelisting resources. Please do also note that it is not possible to use the disallowXYZ functions.
#### `OCP\Security\Events\GenerateSecurePasswordEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-security-events-generatesecurepasswordevent "Link to this heading")
Added in version 18.
Event to request a secure password to be generated.
Since Nextcloud 31 this event also provides a `getContext` method allowing to apply different rules for different password context like account passwords or share passwords.
#### `OCP\Security\Events\ValidatePasswordPolicyEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-security-events-validatepasswordpolicyevent "Link to this heading")
Added in version 18.
This event can be emitted to request a validation of a password. If a password policy app is installed and the password is invalid, an OCPHintException will be thrown.
Since Nextcloud 31 this event also provides a `getContext` method allowing to apply different rules for different password context like account passwords or share passwords.
#### `OCP\Security\FeaturePolicy\AddFeaturePolicyEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-security-featurepolicy-addfeaturepolicyevent "Link to this heading")
Added in version 17.
Event that allows to register a feature policy header to a request.
#### `OCP\Settings\Events\DeclarativeSettingsGetValueEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-settings-events-declarativesettingsgetvalueevent "Link to this heading")
Added in version 29.
#### `OCP\Settings\Events\DeclarativeSettingsRegisterFormEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-settings-events-declarativesettingsregisterformevent "Link to this heading")
Added in version 29.
#### `OCP\Settings\Events\DeclarativeSettingsSetValueEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-settings-events-declarativesettingssetvalueevent "Link to this heading")
Added in version 29.
#### `OCP\Share\Events\BeforeShareCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-share-events-beforesharecreatedevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\BeforeShareDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-share-events-beforesharedeletedevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\ShareAcceptedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-share-events-shareacceptedevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\ShareCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-share-events-sharecreatedevent "Link to this heading")
Added in version 18.
#### `OCP\Share\Events\ShareDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-share-events-sharedeletedevent "Link to this heading")
Added in version 21.
#### `OCP\Share\Events\ShareDeletedFromSelfEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-share-events-sharedeletedfromselfevent "Link to this heading")
Added in version 28.
#### `OCP\Share\Events\VerifyMountPointEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-share-events-verifymountpointevent "Link to this heading")
Added in version 19.
#### `OCP\SpeechToText\Events\TranscriptionFailedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-speechtotext-events-transcriptionfailedevent "Link to this heading")
Added in version 27.
This Event is emitted if a transcription of a media file using a Speech-To-Text provider failed
#### `OCP\SpeechToText\Events\TranscriptionSuccessfulEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-speechtotext-events-transcriptionsuccessfulevent "Link to this heading")
Added in version 27.
This Event is emitted when a transcription of a media file happened successfully
#### `OCP\SystemTag\ManagerEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-systemtag-managerevent "Link to this heading")
Added in version 9.
Class ManagerEvent
#### `OCP\SystemTag\MapperEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-systemtag-mapperevent "Link to this heading")
Added in version 9.
Class MapperEvent
#### `OCP\SystemTag\SystemTagsEntityEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-systemtag-systemtagsentityevent "Link to this heading")
Added in version 9.1.
Changed in version 28.0.0: Dispatched as a typed event
Class SystemTagsEntityEvent
#### `OCP\TaskProcessing\Events\TaskFailedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-taskprocessing-events-taskfailedevent "Link to this heading")
Added in version 30.
#### `OCP\TaskProcessing\Events\TaskSuccessfulEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-taskprocessing-events-tasksuccessfulevent "Link to this heading")
Added in version 30.
#### `OCP\TextProcessing\Events\TaskFailedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-textprocessing-events-taskfailedevent "Link to this heading")
Added in version 27.1.
#### `OCP\TextProcessing\Events\TaskSuccessfulEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-textprocessing-events-tasksuccessfulevent "Link to this heading")
Added in version 27.1.
#### `OCP\TextToImage\Events\TaskFailedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-texttoimage-events-taskfailedevent "Link to this heading")
Added in version 28.
#### `OCP\TextToImage\Events\TaskSuccessfulEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-texttoimage-events-tasksuccessfulevent "Link to this heading")
Added in version 28.
#### `OCP\User\Events\BeforePasswordUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-beforepasswordupdatedevent "Link to this heading")
Added in version 18.
Emitted before the user password is updated.
#### `OCP\User\Events\BeforeUserCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-beforeusercreatedevent "Link to this heading")
Added in version 18.
Emitted before a new user is created on the back-end.
#### `OCP\User\Events\BeforeUserDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-beforeuserdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\BeforeUserLoggedInEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-beforeuserloggedinevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\BeforeUserLoggedInWithCookieEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-beforeuserloggedinwithcookieevent "Link to this heading")
Added in version 18.
Emitted before a user is logged in via remember-me cookies.
#### `OCP\User\Events\BeforeUserLoggedOutEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-beforeuserloggedoutevent "Link to this heading")
Added in version 18.
Emitted before a user is logged out.
#### `OCP\User\Events\OutOfOfficeChangedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-outofofficechangedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period has changed
#### `OCP\User\Events\OutOfOfficeClearedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-outofofficeclearedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period is cleared
#### `OCP\User\Events\OutOfOfficeEndedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-outofofficeendedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period ended
#### `OCP\User\Events\OutOfOfficeScheduledEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-outofofficescheduledevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period is scheduled
#### `OCP\User\Events\OutOfOfficeStartedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-outofofficestartedevent "Link to this heading")
Added in version 28.
Emitted when a user’s out-of-office period started
#### `OCP\User\Events\PasswordUpdatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-passwordupdatedevent "Link to this heading")
Added in version 18.
Emitted when the user password has been updated.
#### `OCP\User\Events\PostLoginEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-postloginevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserChangedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-userchangedevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserCreatedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-usercreatedevent "Link to this heading")
Added in version 18.
Emitted when a new user has been created on the back-end.
#### `OCP\User\Events\UserDeletedEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-userdeletedevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserFirstTimeLoggedInEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-userfirsttimeloggedinevent "Link to this heading")
Added in version 28.
#### `OCP\User\Events\UserLiveStatusEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-userlivestatusevent "Link to this heading")
Added in version 20.
#### `OCP\User\Events\UserLoggedInEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-userloggedinevent "Link to this heading")
Added in version 18.
#### `OCP\User\Events\UserLoggedInWithCookieEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-userloggedinwithcookieevent "Link to this heading")
Added in version 18.
Emitted when a user has been successfully logged in via remember-me cookies.
#### `OCP\User\Events\UserLoggedOutEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-events-userloggedoutevent "Link to this heading")
Added in version 18.
Emitted when a user has been logged out successfully.
#### `OCP\User\GetQuotaEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-user-getquotaevent "Link to this heading")
Added in version 20.
Event to allow apps to
#### `OCP\WorkflowEngine\Events\LoadSettingsScriptsEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-workflowengine-events-loadsettingsscriptsevent "Link to this heading")
Added in version 20.
Emitted when the workflow engine settings page is loaded.
#### `OCP\WorkflowEngine\Events\RegisterChecksEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-workflowengine-events-registerchecksevent "Link to this heading")
Added in version 18.
#### `OCP\WorkflowEngine\Events\RegisterEntitiesEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-workflowengine-events-registerentitiesevent "Link to this heading")
Added in version 18.
#### `OCP\WorkflowEngine\Events\RegisterOperationsEvent`[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-workflowengine-events-registeroperationsevent "Link to this heading")
Added in version 18.
Hooks[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#hooks "Link to this heading")
----------------------------------------------------------------------------------------------------------------
Deprecated since version 18: Use the [OCP event dispatcher](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-event-dispatcher)
instead.
Hooks are used to execute code before or after an event has occurred. This is for instance useful to run cleanup code after users, groups or files have been deleted. Hooks should be registered in the [app.php](https://docs.nextcloud.com/server/31/developer_manual/app_development/init.html)
:
getContainer()\->query('UserHooks')\->register();
The hook logic should be in a separate class that is being registered in the [App constructor](https://docs.nextcloud.com/server/31/developer_manual/basics/dependency_injection.html#using-a-container)
:
getContainer();
/\*\*
\* Controllers
\*/
$container\->registerService('UserHooks', function($c) {
return new UserHooks(
$c\->get(\\OCP\\IUserManager::class)
);
});
}
}
userManager \= $userManager;
}
public function register() {
$callback \= function($user) {
// your code that executes before $user is deleted
};
$this\->userManager\->listen('\\OC\\User', 'preDelete', $callback);
}
}
### Available hooks[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#available-hooks "Link to this heading")
The scope is the first parameter that is passed to the **listen** method, the second parameter is the method and the third one the callback that should be executed once the hook is being called, e.g.:
listen('\\OC\\User', 'preDelete', $callback);
Hooks can also be removed by using the **removeListener** method on the object:
removeListener(null, null, $callback);
The following hooks are available:
### Session[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#session "Link to this heading")
Injectable from the ServerContainer with the `\OCP\IUserSession` service.
Hooks available in scope **\\OC\\User**:
* **preSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **postSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **changeUser** (\\OC\\User\\User $user, string $feature, string $value)
* **preDelete** (\\OC\\User\\User $user)
* **postDelete** (\\OC\\User\\User $user)
* **preCreateUser** (string $uid, string $password)
* **postCreateUser** (\\OC\\User\\User $user)
* **preLogin** (string $user, string $password)
* **postLogin** (\\OC\\User\\User $user, string $password)
* **logout** ()
### UserManager[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#usermanager "Link to this heading")
Injectable from the ServerContainer with the `\OCP\IUserManager` service.
Hooks available in scope **\\OC\\User**:
* **preSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **postSetPassword** (\\OC\\User\\User $user, string $password, string $recoverPassword)
* **preDelete** (\\OC\\User\\User $user)
* **postDelete** (\\OC\\User\\User $user)
* **preCreateUser** (string $uid, string $password)
* **postCreateUser** (\\OC\\User\\User $user, string $password)
### GroupManager[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#groupmanager "Link to this heading")
Hooks available in scope **\\OC\\Group**:
* **preAddUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **postAddUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **preRemoveUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **postRemoveUser** (\\OC\\Group\\Group $group, \\OC\\User\\User $user)
* **preDelete** (\\OC\\Group\\Group $group)
* **postDelete** (\\OC\\Group\\Group $group)
* **preCreate** (string $groupId)
* **postCreate** (\\OC\\Group\\Group $group)
### Filesystem root[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#filesystem-root "Link to this heading")
Injectable from the ServerContainer by calling the method **getRootFolder()**, **getUserFolder()** or **getAppFolder()**.
To enable these events for your app you should add the following to your info.xml file:
Filesystem hooks available in scope **\\OC\\Files**:
* **preWrite** (\\OCP\\Files\\Node $node)
* **postWrite** (\\OCP\\Files\\Node $node)
* **preCreate** (\\OCP\\Files\\Node $node)
* **postCreate** (\\OCP\\Files\\Node $node)
* **preDelete** (\\OCP\\Files\\Node $node)
* **postDelete** (\\OCP\\Files\\Node $node)
* **preTouch** (\\OCP\\Files\\Node $node, int $mtime)
* **postTouch** (\\OCP\\Files\\Node $node)
* **preCopy** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
* **postCopy** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
* **preRename** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
* **postRename** (\\OCP\\Files\\Node $source, \\OCP\\Files\\Node $target)
### Filesystem scanner[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#filesystem-scanner "Link to this heading")
Filesystem scanner hooks available in scope **\\OC\\Files\\Utils\\Scanner**:
* **scanFile** (string $absolutePath)
* **scanFolder** (string $absolutePath)
* **postScanFile** (string $absolutePath)
* **postScanFolder** (string $absolutePath)
Public emitter[](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#public-emitter "Link to this heading")
----------------------------------------------------------------------------------------------------------------------------------
Deprecated since version 18: Use the [OCP event dispatcher](https://docs.nextcloud.com/server/31/developer_manual/basics/events.html#ocp-event-dispatcher)
instead.
tbd
☁️ latest
☁️ Versions
[latest](https://docs.nextcloud.com/server/latest/developer_manual)
[stable](https://docs.nextcloud.com/server/stable/developer_manual)
[30](https://docs.nextcloud.com/server/30/developer_manual)
[29](https://docs.nextcloud.com/server/29/developer_manual)
[28](https://docs.nextcloud.com/server/28/developer_manual)
---
# Controllers — Nextcloud latest Developer Manual latest documentation
* [](https://docs.nextcloud.com/server/stable/developer_manual/index.html)
* [Basic concepts](https://docs.nextcloud.com/server/stable/developer_manual/basics/index.html)
* Controllers
* [Edit on GitHub](https://github.com/nextcloud/documentation/edit/master/developer_manual/basics/controllers.rst)
* * *
Controllers[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#controllers "Link to this heading")
=====================================================================================================================================
Controllers are used to connect [routes](https://docs.nextcloud.com/server/stable/developer_manual/basics/routing.html)
with app logic. Think of it as callbacks that are executed once a request has come in. Controllers are defined inside the **lib/Controller/** directory.
To create a controller, simply extend the Controller class and create a method that should be executed on a request:
$id = 3
// $doMore = false
// $value = 3.5
}
}
The following types will be cast:
* **bool** or **boolean**
* **float**
* **int** or **integer**
### JSON parameters[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#json-parameters "Link to this heading")
It is possible to pass JSON using a POST, PUT or PATCH request. To do that the **Content-Type** header has to be set to **application/json**. The JSON is being parsed as an array and the first level keys will be used to pass in the arguments, e.g.:
POST /index.php/apps/myapp/authors
Content\-Type: application/json
{
"name": "test",
"number": 3,
"publisher": true,
"customFields": {
"mail": "test@example.com",
"address": "Somewhere"
}
}
"test@example.com", "address" => "Somewhere")
}
}
### Reading headers, files, cookies and environment variables[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#reading-headers-files-cookies-and-environment-variables "Link to this heading")
Headers, files, cookies and environment variables can be accessed directly from the request object:
request\->getHeader('Content-Type'); // $\_SERVER\['HTTP\_CONTENT\_TYPE'\]
$cookie \= $this\->request\->getCookie('myCookie'); // $\_COOKIES\['myCookie'\]
$file \= $this\->request\->getUploadedFile('myfile'); // $\_FILES\['myfile'\]
$env \= $this\->request\->getEnv('SOME\_VAR'); // $\_ENV\['SOME\_VAR'\]
}
}
Why should those values be accessed from the request object and not from the global array like $\_FILES? Simple: [because it’s bad practice](http://c2.com/cgi/wiki?GlobalVariablesAreBad)
and will make testing harder.
### Reading and writing session variables[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#reading-and-writing-session-variables "Link to this heading")
To set, get or modify session variables, the ISession object has to be injected into the controller.
Nextcloud will read existing session data at the beginning of the request lifecycle and close the session afterwards. This means that in order to write to the session, the session has to be opened first. This is done implicitly when calling the set method, but would close immediately afterwards. To prevent this, the session has to be explicitly opened by calling the reopen method.
Alternatively, you can use the `#[UseSession]` attribute to automatically open and close the session for you.
use OCP\\AppFramework\\Controller;
use OCP\\AppFramework\\Http\\Attribute\\UseSession;
use OCP\\AppFramework\\Http\\Response;
class PageController extends Controller {
#\[UseSession\] public function writeASessionVariable(): Response {
// ...
}
}
Note
The `#[UseSession]` was added in Nextcloud 26 and requires PHP 8.0 or later. If your app targets older releases and PHP 7.x then use the deprecated `@UseSession` annotation.
/\*\*
\* @UseSession \*/
public function writeASessionVariable(): Response {
// ....
}
In case the session may be read and written by concurrent requests of your application, keeping the session open during your controller method execution may be required to ensure that the session is locked and no other request can write to the session at the same time. When reopening the session, the session data will also get updated with the latest changes from other requests. Using the annotation will keep the session lock for the whole duration of the controller method execution.
For additional information on how session locking works in PHP see the article about [PHP Session Locking: How To Prevent Sessions Blocking in PHP requests](https://ma.ttias.be/php-session-locking-prevent-sessions-blocking-in-requests/)
.
Then session variables can be accessed like this:
Note
The session is closed automatically for writing, unless you add the `#[UseSession]` attribute!
session \= $session;
}
#\[UseSession\]
public function writeASessionVariable(): Response {
// read a session variable
$value \= $this\->session\['value'\];
// write a session variable
$this\->session\['value'\] \= 'new value';
}
}
### Setting cookies[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#setting-cookies "Link to this heading")
Cookies can be set or modified directly on the response class:
addCookie('foo', 'bar');
$response\->addCookie('bar', 'foo', new DateTime('2015-01-01 00:00'));
return $response;
}
/\*\*
\* Invalidates the cookie "foo"
\* Invalidates the cookie "bar" and "bazinga"
\*/
public function invalidateCookie(): TemplateResponse {
$response \= new TemplateResponse(...);
$response\->invalidateCookie('foo');
$response\->invalidateCookies(array('bar', 'bazinga'));
return $response;
}
}
Responses[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#responses "Link to this heading")
---------------------------------------------------------------------------------------------------------------------------------
Similar to how every controller receives a request object, every controller method has to return a Response. This can be in the form of a Response subclass or in the form of a value that can be handled by a registered responder.
There are different kinds of responses available, like HTML-based responses, data responses, or other. The app decides of which kind the response is, by returning an appropriate `Response` object in the corresponding controller method. The following sections give an overview over the various kinds and how to implement them.
HTML-based Responses[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#html-based-responses "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------
HTML pages are typically served using template responses. This is typically used as a starting point to load the website. This code linked by the template is by default encapsulated by the server to provide some common styling (e.g. the header row). The code then uses JavaScript to load further components (see [Frontend building in Vue](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/js.html#applicationjs)
) and the actual data. This section only focuses on the actual HTML content, not the data to fill into the dynamic pages.
### Templates[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#templates "Link to this heading")
A [template](https://docs.nextcloud.com/server/stable/developer_manual/basics/front-end/templates.html)
can be rendered by returning a TemplateResponse. A TemplateResponse takes the following parameters:
* **appName**: tells the template engine in which app the template should be located
* **templateName**: the name of the template inside the templates/ folder without the .php extension
* **parameters**: optional array parameters that are available in the template through $\_, e.g.:
array('key' \=> 'something')
can be accessed through:
$\_\['key'\]
* **renderAs**: defaults to _user_, tells Nextcloud if it should include it in the web interface, or in case _blank_ is passed solely render the template
'hi');
return new TemplateResponse($this\->appName, $templateName, $parameters);
}
}
### Public page templates[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#public-page-templates "Link to this heading")
For public pages, that are rendered to users who are not logged in to the Nextcloud instance, a `OCP\\AppFramework\\Http\\Template\\PublicTemplateResponse` should be used, to load the correct base template. It also allows adding an optional set of actions that will be shown in the top right corner of the public page.
appName, 'main', \[\]);
$template\->setHeaderTitle('Public page');
$template\->setHeaderDetails('some details');
$template\->setHeaderActions(\[\
new SimpleMenuAction('download', 'Label 1', 'icon-css-class1', 'link-url', 0),\
new SimpleMenuAction('share', 'Label 2', 'icon-css-class2', 'link-url', 10),\
\]);
return $template;
}
}
The header title and subtitle will be rendered in the header, next to the logo. The action with the highest priority (lowest number) will be used as the primary action, others will shown in the popover menu on demand.
A `OCP\\AppFramework\\Http\\Template\\SimpleMenuAction` will be a link with an icon added to the menu. App developers can implement their own types of menu renderings by adding a custom class implementing the `OCP\\AppFramework\\Http\\Template\\IMenuAction` interface.
Data-based responses[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#data-based-responses "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------
In contrast to the HTML template responses, the data responses return some user-data in packed form. There are different encodings thinkable like JSON, XML, or other formats. The main point is that the data is requested by the browser using JavaScript on behalf of the shown website. The user only indirectly requested the data by user interaction with the frontend.
### OCS[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#ocs "Link to this heading")
Note
This is purely for compatibility reasons. If you are planning to offer an external API, go for a [REST APIs](https://docs.nextcloud.com/server/stable/developer_manual/digging_deeper/rest_apis.html#rest-apis)
instead.
In order to simplify exchange of data between the Nextcloud backend and any client (be it the web frontend or whatever else), the OCS API has been introduced. To use OCS in your API you can use the **OCP\\AppFramework\\OCSController** base class and return your data in the form of a **DataResponse** in the following way:
\[\
\[\
'name' \=> 'Share#getShares',\
'url' \=> '/api/v1/shares',\
'verb' \=> 'GET',\
\],\
\],\
\];
Now your method will be reachable via `/ocs/v2.php/apps//api/v1/shares`
Added in version 29: You can use the attribute `ApiRoute` as described in [Routing](https://docs.nextcloud.com/server/stable/developer_manual/basics/routing.html)
instead of the entry in `appinfo/routes.php` as an alternative.
### JSON[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#json "Link to this heading")
Returning JSON is simple, just pass an array to a JSONResponse:
'hi');
return new JSONResponse($params);
}
}
Because returning JSON is such a common task, there’s even a shorter way to do this:
'hi');
}
}
Why does this work? Because the dispatcher sees that the controller did not return a subclass of a Response and asks the controller to turn the value into a Response. That’s where responders come in.
### Handling errors[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#handling-errors "Link to this heading")
Sometimes a request should fail, for instance if an author with id 1 is requested but does not exist. In that case use an appropriate [HTTP error code](https://en.wikipedia.org/wiki/List_of_HTTP_status_codes#4xx_Client_Error)
to signal the client that an error occurred.
Each response subclass has access to the **setStatus** method which lets you set an HTTP status code. To return a JSONResponse signaling that the author with id 1 has not been found, use the following code:
registerResponder('xml', function($value) {
if ($value instanceof DataResponse) {
return new XMLResponse(
$value\->getData(),
$value\->getStatus(),
$value\->getHeaders()
);
} else {
return new XMLResponse($value);
}
});
return array('test' \=> 'hi');
}
}
Note
The above example would only return XML if the **format** parameter was _xml_. If you want to return an XMLResponse regardless of the format parameter, extend the Response class and return a new instance of it from the controller method instead.
Because returning values works fine in case of a success but not in case of failure that requires a custom HTTP error code, you can always wrap the value in a **DataResponse**. This works for both normal responses and error responses.
'not found!'), Http::STATUS\_NOT\_FOUND);
}
}
}
Miscellaneous responses[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#miscellaneous-responses "Link to this heading")
-------------------------------------------------------------------------------------------------------------------------------------------------------------
Some special responses are available as well. These are discussed here.
### Redirects[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#redirects "Link to this heading")
A redirect can be achieved by returning a RedirectResponse:
addHeader('Content-Type', 'application/xml');
$this\->xml \= $xml;
}
public function render(): string {
$root \= new SimpleXMLElement('');
array\_walk\_recursive($this\->xml, array ($root, 'addChild'));
return $xml\->asXML();
}
}
### Streamed and lazily rendered responses[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#streamed-and-lazily-rendered-responses "Link to this heading")
By default all responses are rendered at once and sent as a string through middleware. In certain cases this is not a desirable behavior, for instance if you want to stream a file in order to save memory. To do that use the now available **OCP\\AppFramework\\Http\\StreamResponse** class:
index()` method should not check the CSRF token because it has not yet been sent to the client and because of that can’t work.
To turn off checks the following _Attributes_ can be added before the controller:
* `#[NoAdminRequired]`: Also users that are not admins can access the page
* `#[PublicPage]`: Everyone can access the page without having to log in
* `#[NoTwoFactorRequired]`: A user can access the page before the two-factor challenge has been passed (use this wisely and only in two-factor auth apps, e.g. to allow setup during login)
* `#[NoCSRFRequired]`: Don’t check the CSRF token (use this wisely since you might create a security hole; to understand what it does see [CSRF in the security section](https://docs.nextcloud.com/server/stable/developer_manual/prologue/security.html#cross-site-request-forgery)
)
Note
The attributes are only available in Nextcloud 27 or later. In older versions annotations with the same names exist:
* `@NoAdminRequired` instead of `#[NoAdminRequired]`
* `` @PublicPage` `` instead of `#[PublicPage]`
* `` @NoTwoFactorRequired` `` instead of `#[NoTwoFactorRequired]`
* `` @NoCSRFRequired` `` instead of `#[NoCSRFRequired]`
In the following some examples of configurations are given.
#### Showing an HTML page by the user[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#showing-an-html-page-by-the-user "Link to this heading")
A typical app needs an `index.html` page to show all content within. This page should be visible by all users in the instance. Therefore, you need to loosen the restriction from admins only (`#[NoAdminRequired]`). Additionally, as the user might not have a CSRF checker cookie set yet, the CSRF checks should be disabled (which is fine as this is a template response).
appName, 'main');
}
}
If the page should only be visible to the admin, you can keep the restrictive default by omitting the attribute `#[NoAdminRequired]`.
#### Getting data from the backend using AJAX requests[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#getting-data-from-the-backend-using-ajax-requests "Link to this heading")
Data for the frontend needs to be made available from the backend. Here, OCS is the suggested way to go. Here is the example from [OCS controllers](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#ocscontroller)
:
auth->isSuccessful here is just an
// example.
if (!$this\->auth\->isSuccessful()) {
$templateResponse\->throttle(); }
return $templateResponse;
}
}
A controller can also have multiple factors to brute force against. In this case you can specify multiple attributes and then in the throttle you specify the action which was violated. This is especially useful when a secret, in the sample below token, could be guessed on multiple endpoints e.g. a share token on the API level, preview endpoint, frontend controller, etc. while another secret (password), is specific to this one controller method.
shareManager\->getByToken($token)) {
$templateResponse\->throttle(\['action' \=> 'token'\]); }
// …
if (!$share\->verifyPassword($password)) {
$templateResponse\->throttle(\['action' \=> 'password'\]); }
return $templateResponse;
}
}
### Modifying the content security policy[](https://docs.nextcloud.com/server/stable/developer_manual/basics/controllers.html#modifying-the-content-security-policy "Link to this heading")
By default Nextcloud disables all resources which are not served on the same domain, forbids cross domain requests and disables inline CSS and JavaScript by setting a [Content Security Policy](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Introducing_Content_Security_Policy)
. However if an app relies on third-party media or other features which are forbidden by the current policy the policy can be relaxed.
Note
Double check your content and edge cases before you relax the policy! Also read the [documentation provided by MDN](https://developer.mozilla.org/en-US/docs/Web/Security/CSP/Introducing_Content_Security_Policy)
To relax the policy pass an instance of the ContentSecurityPolicy class to your response. The methods on the class can be chained.
The following methods turn off security features by passing in **true** as the **$isAllowed** parameter
* **allowInlineScript** (bool $isAllowed)
* **allowInlineStyle** (bool $isAllowed)
* **allowEvalScript** (bool $isAllowed)
* **useStrictDynamic** (bool $isAllowed)
Trust all scripts that are loaded by a trusted script, see ‘script-src’ and ‘strict-dynamic’
* **useStrictDynamicOnScripts** (bool $isAllowed)
Trust all scripts that are loaded by a trusted script which was loaded using a `