diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index b6fc5bf..4e1307a 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -188,3 +188,5 @@ jobs:
- uses: actions/checkout@v4
- uses: jupyterlab/maintainer-tools/.github/actions/base-setup@v1
- uses: jupyterlab/maintainer-tools/.github/actions/check-links@v1
+ with:
+ ignore_glob: docs/*.md
diff --git a/.readthedocs.yaml b/.readthedocs.yaml
new file mode 100644
index 0000000..4258ed9
--- /dev/null
+++ b/.readthedocs.yaml
@@ -0,0 +1,17 @@
+version: 2
+
+build:
+ os: ubuntu-24.04
+ tools:
+ python: mambaforge-23.11
+ jobs:
+ pre_build:
+ - pip install -v .
+
+conda:
+ environment: docs/environment-docs.yml
+
+sphinx:
+ builder: html
+ configuration: docs/conf.py
+ fail_on_warning: true
diff --git a/README.md b/README.md
index 48be0c1..4624cf5 100644
--- a/README.md
+++ b/README.md
@@ -119,6 +119,25 @@ or:
jupyter lite serve --LiteBuildConfig.extra_http_headers=Cross-Origin-Embedder-Policy=require-corp --LiteBuildConfig.extra_http_headers=Cross-Origin-Opener-Policy=same-origin
```
+### Building the documentation
+
+The project documentation includes a demo deployment, and is built on every PR so that the changes can be checked manually before merging. To build the documentation and demo locally use:
+
+```bash
+micromamba create -f docs/environment-docs.yml
+micromamba activate terminal-docs
+pip install -v .
+cd docs
+make html
+```
+
+To serve this locally use:
+
+```bash
+cd _build/html
+python -m http.server
+```
+
### Packaging the extension
See [RELEASE](RELEASE.md)
diff --git a/docs/Makefile b/docs/Makefile
new file mode 100644
index 0000000..d4bb2cb
--- /dev/null
+++ b/docs/Makefile
@@ -0,0 +1,20 @@
+# Minimal makefile for Sphinx documentation
+#
+
+# You can set these variables from the command line, and also
+# from the environment for the first two.
+SPHINXOPTS ?=
+SPHINXBUILD ?= sphinx-build
+SOURCEDIR = .
+BUILDDIR = _build
+
+# Put it first so that "make" without argument is like "make help".
+help:
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
+
+.PHONY: help Makefile
+
+# Catch-all target: route all unknown targets to Sphinx using the new
+# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
+%: Makefile
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
diff --git a/docs/_static/terminal_logo_dark.svg b/docs/_static/terminal_logo_dark.svg
new file mode 100644
index 0000000..feda23d
--- /dev/null
+++ b/docs/_static/terminal_logo_dark.svg
@@ -0,0 +1,67 @@
+
+
+
+
diff --git a/docs/_static/terminal_logo_light.svg b/docs/_static/terminal_logo_light.svg
new file mode 100644
index 0000000..de3402f
--- /dev/null
+++ b/docs/_static/terminal_logo_light.svg
@@ -0,0 +1,67 @@
+
+
+
+
diff --git a/docs/changelog.md b/docs/changelog.md
new file mode 120000
index 0000000..04c99a5
--- /dev/null
+++ b/docs/changelog.md
@@ -0,0 +1 @@
+../CHANGELOG.md
\ No newline at end of file
diff --git a/docs/conf.py b/docs/conf.py
new file mode 100644
index 0000000..46c10e0
--- /dev/null
+++ b/docs/conf.py
@@ -0,0 +1,37 @@
+from datetime import date
+import json
+from pathlib import Path
+
+PACKAGE_JSON_FILENAME = Path(__file__).parent.parent / "package.json"
+PACKAGE_JSON = json.loads(PACKAGE_JSON_FILENAME.read_text(encoding="utf-8"))
+
+project = 'JupyterLite Terminal'
+author = PACKAGE_JSON["author"]["name"]
+copyright = f"2024-{date.today().year}, {author}"
+release = PACKAGE_JSON["version"]
+
+extensions = [
+ "jupyterlite_sphinx",
+ "myst_parser"
+]
+
+templates_path = ['_templates']
+exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
+
+html_static_path = ['_static']
+html_theme = "pydata_sphinx_theme"
+html_theme_options = {
+ "github_url": PACKAGE_JSON["homepage"],
+ "logo": {
+ "alt_text": "JupyterLite Terminal - Home",
+ "image_dark": "_static/terminal_logo_dark.svg",
+ "image_light": "_static/terminal_logo_light.svg",
+ "text": "JupyterLite Terminal",
+ }
+}
+html_title = "JupyterLite Terminal"
+
+# jupyterlite_sphonx settings
+jupyterlite_contents = "../deploy/contents/"
+jupyterlite_dir = "../deploy/"
+jupyterlite_silence = False
diff --git a/docs/environment-docs.yml b/docs/environment-docs.yml
new file mode 100644
index 0000000..d12f41a
--- /dev/null
+++ b/docs/environment-docs.yml
@@ -0,0 +1,17 @@
+name: terminal-docs
+channels:
+ - conda-forge
+dependencies:
+ # General build dependencies
+ - micromamba
+ - nodejs =20
+ - python =3.13
+
+ # Jupyter dependencies
+ - jupyterlite-core >=0.6,<0.8.0
+
+ # Docs dependencies
+ - jupyterlite-sphinx
+ - myst-parser
+ - pydata-sphinx-theme
+ - sphinx
diff --git a/docs/index.md b/docs/index.md
new file mode 100644
index 0000000..0042241
--- /dev/null
+++ b/docs/index.md
@@ -0,0 +1,13 @@
+# JupyterLite Terminal
+
+Blah blah blah.
+
+## Contents
+
+```{toctree}
+:maxdepth: 1
+
+changelog
+```
+
+Link to deployment.
diff --git a/docs/make.bat b/docs/make.bat
new file mode 100644
index 0000000..32bb245
--- /dev/null
+++ b/docs/make.bat
@@ -0,0 +1,35 @@
+@ECHO OFF
+
+pushd %~dp0
+
+REM Command file for Sphinx documentation
+
+if "%SPHINXBUILD%" == "" (
+ set SPHINXBUILD=sphinx-build
+)
+set SOURCEDIR=.
+set BUILDDIR=_build
+
+%SPHINXBUILD% >NUL 2>NUL
+if errorlevel 9009 (
+ echo.
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
+ echo.installed, then set the SPHINXBUILD environment variable to point
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
+ echo.may add the Sphinx directory to PATH.
+ echo.
+ echo.If you don't have Sphinx installed, grab it from
+ echo.https://www.sphinx-doc.org/
+ exit /b 1
+)
+
+if "%1" == "" goto help
+
+%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+goto end
+
+:help
+%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
+
+:end
+popd