diff --git a/{{cookiecutter.project_name}}/.github/workflows/deploy-docs.yaml b/{{cookiecutter.project_name}}/.github/workflows/deploy-docs.yaml
index 9780a9c..784dca6 100644
--- a/{{cookiecutter.project_name}}/.github/workflows/deploy-docs.yaml
+++ b/{{cookiecutter.project_name}}/.github/workflows/deploy-docs.yaml
@@ -16,7 +16,7 @@ jobs:
 
     steps:
       - name: Checkout
-        uses: actions/checkout@v3
+        uses: actions/checkout@v4
         with:
           fetch-depth: 0  # otherwise, you will failed to push refs to dest repo
 
diff --git a/{{cookiecutter.project_name}}/.github/workflows/test_pages_build.yaml b/{{cookiecutter.project_name}}/.github/workflows/test_pages_build.yaml
new file mode 100644
index 0000000..3e7b5f8
--- /dev/null
+++ b/{{cookiecutter.project_name}}/.github/workflows/test_pages_build.yaml
@@ -0,0 +1,44 @@
+name: Preview {{cookiecutter.__project_slug}} documentation build
+
+on:
+  pull_request:
+    types:
+      - opened
+      - reopened
+      - synchronize
+
+concurrency: preview-${{ github.ref }}
+
+jobs:
+  run:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Checkout
+        uses: actions/checkout@v4
+        with:
+          fetch-depth: 0
+
+      - name: Set up Python 3
+        uses: actions/setup-python@v4
+        with:
+          python-version: 3.9
+
+      - name: Install Poetry
+        run: pipx install poetry
+
+      - name: Install dependencies
+        run: poetry install -E docs
+
+      - name: Build documentation
+        run: |
+          mkdir -p site
+          touch site/.nojekyll
+          make gendoc
+          ([ ! -f docs/about.md ] && cp src/docs/about.md docs/) || true
+          poetry run mkdocs build -d site
+
+      - name: Deploy preview
+        uses: rossjrw/pr-preview-action@v1
+        with:
+          source-dir: site/
+          preview-branch: gh-pages