mdjango
v0.1.0rc2.dev3+g175c8392a llms.txtllms-full.txt github

How-to

Export a static site#

Goal: produce a directory a static file host can serve, identical to the running site, for a deployment that needs the docs and nothing else.

Serving from your Django process is the primary way to run mdjango, and the one the rest of these docs assume. The export exists for the case where no Django process will run: a docs-only host, a preview bucket, an offline copy.

You need: the project configured as for runtime. The export uses the same settings, Content tree and templates. The command's options are in the mdjango_build reference.

Build the dist#

python manage.py mdjango_build
exported N pages + N text files + N static files to dist

The output directory defaults to ./dist. Pass a path as the first argument to change it. The layout mirrors the live URLs, one directory per page, with file-shaped URLs written as files:

dist/
  docs/
    index.html                          # /docs/
    getting-started/
      install-and-mount/index.html      # /docs/getting-started/install-and-mount/
      install-and-mount.md              # the page's markdown alternate
    search-index.json
    llms.txt
    llms-full.txt
    index.md
  static/
    mdjango/                            # stylesheet, fonts, controllers, vendored JS

docs/ is your mount prefix. static/ is your STATIC_URL. The static destination is deleted and rewritten on every build. Page files are overwritten in place.

Build with the default static storage#

The export copies mdjango's static tree with its plain filenames. If your production settings use a manifest storage backend (hashed filenames, as WhiteNoise's CompressedManifestStaticFilesStorage does), {% static %} writes hashed URLs into the HTML that the export never creates, and every stylesheet and script 404s.

Run the export with the default staticfiles storage. Keep the manifest backend for the runtime site only, or point DJANGO_SETTINGS_MODULE at a settings module that omits it for the build.

Add your own static files#

Only mdjango's own static tree is copied. A stylesheet you load after mdjango's, or an image linked from a page, is referenced by the HTML but not written. Copy those into dist/static/ after the build:

python manage.py mdjango_build
cp -r acme-static/. dist/static/acme/

Host it at the same prefix#

The exported HTML references /docs/… and /static/… as absolute paths, the same ones the running site uses. Serve dist/ as the root of a host so that /docs/ resolves to dist/docs/index.html. Uploading only dist/docs/ under a different prefix breaks every stylesheet, script and search request. Nothing rewrites paths; the dist is not relocatable. To change the prefix, change the mount in urls.py and rebuild.

To preview locally:

python -m http.server --directory dist 8000

Open http://127.0.0.1:8000/docs/. Search works from the exported search-index.json. Dark mode, copy buttons and the drawer work from the exported controllers. Nothing is fetched from the network.

Export without drafts#

Drafts are exported when MDJANGO_INCLUDE_DRAFTS is true, which defaults to DEBUG. Run the export with the settings you would deploy:

DJANGO_SETTINGS_MODULE=config.settings_production python manage.py mdjango_build

MDJANGO_CACHE_SECONDS has no effect on the export. The file server sets its own headers, and there is no login gate: anything that needs authentication stays on the Django process.

Know the limits#

  • Without a root _index.md the first Page is written twice: once at /docs/ and once at its own URL. No canonical link is emitted.
  • Non-markdown files in the Content tree are not copied.
  • The export is a management command, not a standalone tool. The build environment needs the project's settings importable.