Open-source project
nextcloud/documentation avatar
nextcloud/documentation

nextcloud/documentation: the source of three manuals

📘 Nextcloud documentation

635 stars2,562 forksJavaScriptNOASSERTION

At a glance

What is it?
The Nextcloud documentation repository holds the users' manual, the administration manual, and the developers manual as reStructuredText sources built with Sphinx. Its readme is short, and the two decisions in it are the interesting ones: page names are treated as an API that never moves, and every contribution is signed off under the Developer Certificate of Origin.
Who is it for?
nextcloud/documentation fits a Nextcloud administrator or user who wants to fix a page that is wrong, and it fits a developer who wants the manual that describes the API of the server they are calling. It does not fit someone who wants a rendered copy offline, because the repository is the source rather than the site.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly JavaScript, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

Three manuals, one repository

The repository hosts three manuals, and the list is short enough to quote: the users' manual, the administration manual, and the developers manual. Each one is a top level directory in the tree, and each one has its own build output directory inside it.

The published result is at docs.nextcloud.com, and the readme is candid about what editing it involves: to edit it yourself you need to tinker a bit with Git and Sphinx. That sentence is the honest summary of a documentation project that is a source tree rather than a wiki.

The other structural decision is the branch model, and it is the one that catches out first-time contributors. The stable branches are for the respective release, so a branch named for version 14 or 15, and the master branch is the latest version. The instruction is to work in the appropriate branch, and the readme adds the consequence: if your edits apply to several versions of the manual, you should be prepared to backport them.

That last point is the difference between a documentation project and a website. A website publishes one version of the truth. A manual for software that people run has to describe the versions they are running, and the same fix often has to be applied in more than one branch.

There is also a note about one file that is not edited here at all. The server configuration sample page is auto-generated from the configuration sample file in the core server repository, so a change to that page has to be made in the server project instead. It is the clearest example of the general rule this repository lives by, which is that the documentation follows the code.

Why a page name is an API

The structure section of the readme is the most opinionated paragraph in the whole document, and it is about not moving things.

The instruction is to think about structure, and the reasoning follows. The project tries not to move or rename pages once they are created, because a great many external sources link to the documentation, including the indexing by search engines. So once a page has a name, it has to stay in that location and with that name.

The readme then makes the analogy explicit, and it is the right one: think of it as API stability. The guarantee has to be made as strong as possible, and renaming or moving is only allowed in exceptional circumstances, and only when a redirect is put in place.

That analogy tells you how to read every other convention in the repository. A URL is a promise to somebody outside the project, and the cost of breaking it falls on the person who made the link, not on the project. The redirect is the mitigation, and it is allowed as a safety net rather than as a routine step.

The same reasoning explains the other editorial rules. Prose lines are wrapped at 120 characters where practical, with long URLs, code examples, and table cells allowed to exceed the limit. Spelling and capitalisation have their own short list, which currently names the App Store, the verb to synchronise, and the two spellings of web, and the note says that this list may be moved to its own page as it grows, which is a sign the project expects it to keep changing.

There is a codespell configuration and an ignore file in the tree, which is a small automation for the same class of problem: a spelling mistake in a manual is a bug, and the tool that finds them runs in continuous integration.

Sphinx, and a toolchain pinned to exact versions

The source files are written in reStructuredText and built with the Sphinx documentation generator, and the readme notes that the syntax can also be edited from GitHub.

The requirements file shows what the build actually needs, and the pinning is absolute: every dependency is on an exact version, with the generator at 8.1.3, the theme at 3.1.0, and the document utilities at 0.21.2. There is no range syntax anywhere in the list, which is an unusual and deliberate choice for a set of documentation dependencies.

The reason is a practical one about reproducibility. A manual has to build the same way on a contributor's laptop, on the continuous integration runner, and on whatever machine publishes the site, and a floating dependency in a documentation build produces a build that breaks in a pull request for reasons that have nothing to do with the change.

The list also shows the ambitions of the build. There is a package for a dark mode, which is the kind of thing that only matters once a documentation set has an audience large enough to read at night. There is a package for copying buttons, so that a reader can copy a command from a code block. There is a package that renders mathematical notation, one that renders diagrams, one that provides a not-found page, and a redirect helper, which is the mechanism that makes the page-move policy workable rather than aspirational.

And there is a pair of output packages, one for PDF and one for EPUB, which tells you that the manual is expected to be read on a device that is not a browser as well as on one that is.

The list also includes a linter for the source format itself, which is the documentation equivalent of a type checker. It runs over the reStructuredText and catches malformed markup before a human reviewer has to.

Building it locally, and the four things the build produces

The building section gives the automated path and the manual one, and the manual one is the recommended one.

The automated path is short. Fetch the sources, change into the directory, check out the branch for the version you want, install the requirements with pip, and run make all.

The manual path is what the readme pushes you towards, and it comes in two variants. One uses pipenv: install pipenv, change into the environment with the shell command, install the requirements, and then use the make targets to build whatever you want, for example the HTML flavour of all the manuals. The build assets land in the individual documentation subdirectories, such as the HTML build of the developers manual under its own directory.

The other variant uses a standard virtual environment: install the venv package for Python, create the environment once inside the repository, activate it, install the requirements, and then use the same make targets.

The reason for preferring the local build is stated plainly. A complete Sphinx build environment on your own machine lets you make your own local builds, which is the fastest and best way to preview for errors. The generator will report syntax errors, missing images, and formatting errors, and the preview on GitHub is not complete and misses many mistakes.

That is the argument, and it is a good one: a documentation pull request that is reviewed by a human on a web preview is a review of something other than what will be published.

The make targets themselves are worth reading, because they show the shape of the build.

makefile
all: html pdf epub

html: admin-manual-html user-manual-html developer-manual-html
pdf: admin-manual-pdf user-manual-pdf
epub: admin-manual-epub user-manual-epub developer-manual-epub

The top level target builds everything: HTML, PDF, and EPUB. The HTML target fans out into one target per manual, and the developers manual target has a dependency on the OpenAPI specification, which is fetched first. The PDF target builds only the two manuals that have a PDF edition, and the EPUB target covers all three. Each target cleans its own build directory before running, which keeps a stale page from surviving a rename.

The OpenAPI pipeline, and where the developer manual gets its API

One make target is more interesting than the rest, and it is the one that explains why the developers manual is not hand-written.

The developers manual HTML and EPUB targets both depend on a target that fetches the server sources, copies the generated OpenAPI document into the static directory of the manual, and then downloads a web component bundle and its stylesheet from a package registry at a pinned version. The result is a manual page that renders the live API description of the server, produced from the server code itself rather than transcribed by hand.

The first step is the significant one. The script in the build directory takes a branch name as an argument, so the API description is produced from a specific branch of the server project, which is how the manual stays consistent with the code it describes.

That is the same principle as the auto-generated configuration sample page, applied at a larger scale. In both cases the documentation is derived from the implementation, and the cost is that the pipeline has to run, which is why the make target exists and why the developers manual targets depend on it.

The two outputs from the OpenAPI target are also worth distinguishing. The JSON description is the data. The downloaded web component is the renderer that turns it into something readable, and it comes from a third party at a fixed version, so the manual's API page depends on code that lives outside both projects.

Translations, sign-off, and the contribution flow

Two processes sit on top of the source tree, and both are worth understanding before you contribute.

The first is translation. The user manual is the one that is translated, through a hosted translation platform, and the readme links both the platform project for the user documentation and a separate guide for developers who want to make the translation process easier, including how the Sphinx integration is set up. The build section then describes how to produce a translated version yourself: build the English version first, run a script that creates the translation files, build the German version with a language specific target, and find the output in the German build directory. The instruction to delete the whole build directory before building another language is there because the build output for one language is not a safe basis for the next.

The second is sign-off. Contributing requires a GitHub account, and the readme asks you to sign off your commits to certify adherence to the Developer Certificate of Origin, with the exact line to include, and with a note that the commit messages need the name and email address of the contributor. If you are on the command line and your name and email are configured, the commit command with the sign-off flag does it for you. And in both settings your email address has to match the one in your GitHub profile, which if you have privacy enabled is the noreply form of your username.

The final instruction is the one that catches people out: in the local case the email address used for the commit is the one GitHub shows, not the one you type into the terminal by habit.

Around that sits the branching advice. Create a new branch against the master or stable branch you are editing, make your edits, push the branch, and open a pull request. For small fixes you can edit on GitHub directly, and for substantial work the readme is explicit that a local build gives you better control, which is the same argument as the build section makes.

The repository also carries a style guide as a separate document, along with the editor configuration and the agent instruction files, so the conventions a contributor is asked to follow are written down in one place rather than in the readme.

Editorial conclusion

nextcloud/documentation fits a Nextcloud administrator or user who wants to fix a page that is wrong, and it fits a developer who wants the manual that describes the API of the server they are calling. It does not fit someone who wants a rendered copy offline, because the repository is the source rather than the site. Verify first that you are on the right branch, since the stable branches correspond to released versions and the master branch is the newest, that a page you want to move is genuinely a case for the exception, because renaming needs a redirect and an exceptional justification, and that your commit is signed off, because the merge of an unsigned contribution is the most likely way to have your work sit unreviewed.

Frequently asked questions

What does the nextcloud/documentation repository contain?

The source of three Nextcloud manuals, the users' manual, the administration manual, and the developers manual, written in reStructuredText and built with Sphinx. The published result is at docs.nextcloud.com, and the repository also holds the build files, the style guide, and the shared assets.

Which branch should I edit for a Nextcloud documentation fix?

The stable branches correspond to the respective releases, and the master branch is the latest version. If your edit applies to several versions of the manual you should expect to backport it, because the same manual is published for each release.

Why are Nextcloud documentation pages never renamed?

Because many external sources link to the documentation, including search engine indexes, so a page name is treated like an API: once created, it has to stay in that location with that name. Renaming is allowed only in exceptional circumstances and only when a redirect is put in place.

How do I build the Nextcloud documentation locally?

Install the requirements with pip, either inside a pipenv shell or inside a standard Python virtual environment, and then run the make targets, for example the HTML target for the manuals or the all target for everything. The local build is recommended because the generator reports syntax errors, missing images, and formatting errors that the preview on GitHub misses.

How is the API reference in the Nextcloud developers manual produced?

From the server code. A make target fetches the server sources for a given branch, copies the generated OpenAPI document into the manual's static directory, and downloads the web component that renders it at a pinned version. The developers manual build targets depend on that step.

Official sources

  1. Issues
  2. nextcloud/documentation on GitHub
  3. Project website
  4. README
  5. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/nextcloud-documentation.svg)](https://hysenlabs.com/projects/nextcloud-documentation)

Was this useful?