Skip to content


Plugin for MkDocs to programmatically generate documentation pages during the build


pip install mkdocs-gen-files


Activate the plugin in mkdocs.yml (scripts is a required list of Python scripts to execute, always relative to mkdocs.yml):

  - search
  - gen-files:
        -  # or any other name or path

Then create such a script (this is relative to the root, not to the docs directory).

import mkdocs_gen_files

with"", "w") as f:
    print("Hello, world!", file=f)

Or something a bit more interesting:

import mkdocs_gen_files

for total in range(19, 100, 20):
    filename = f"sample/{total}"

    with, "w") as f:
        for i in reversed(range(1, total + 1)):
            print(f"{i} bottles of beer on the wall, {i} bottles of beer  ", file=f)
            print(f"Take one down and pass it around, **{i-1}** bottles of beer on the wall\n", file=f)

    mkdocs_gen_files.set_edit_path(filename, "")

This adds programmatically generated pages to our site. This example script has been applied to this very site, you can see sample/ etc.

Use cases#

You might be wondering, what's the point of this?

The original use case was with mkdocstrings - generating pages with just stubs for each item in API documentation, so that they can be populated by the tools.

You can also modify all existing files on the site in some way. Or perhaps copy files from somewhere on the fly.


For all intents and purposes, please conceptualize the function as the actual open() function running under the docs_dir (./docs/ by default, picked up from mkdocs.yml). In fact, if a script using mkdocs_gen_files is launched standalone, that is actually the case; you can use that to try out how the results look (though manual cleanup will be required).

But if attached as a MkDocs plugin, it represents that directory only virtually; all file modifications affect only the ongoing site build and aren't persisted. But you can still read (and even virtually append to) the actual files under docs/.

This is implemented by implicitly transferring the files to a temporary directory (which is what you really end up opening) and telling MkDocs to fetch them from there instead. Note that this happens before MkDocs reads any of the doc files, so all of the outputs should look to it exactly as if the files were there all along.

All file modes are supported (even e.g. ab+). You could even open a file to read it, replace something in it, and write it back anew. Though at that point you may be better served by the "macros" plugin.

Note that this function is separate from the top-level built-in open(), which is unaffected and can still be used normally, relative to the current working directory (which is not changed to ./docs/, instead it's just the directory that you ran mkdocs from).