Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- **Docs: navigation and SEO polish.** A stable/latest version switcher in the navbar
(`docs/_static/switcher.json`); a custom `robots.txt` that keeps the ~60 thin
`_modules/` source-view pages out of crawlers (documentation pages allowed as
before); "Tutorial N:" prefixes dropped from 8 notebook H1s so page titles and
search-result snippets lead with the topic (page URLs unchanged - only the H1's
own fragment id changes, and an H1 anchor resolves to the page top that the bare
URL already opens; sidebar labels were already short-form); the 5 section landing
pages are now linked from `diff_diff/guides/llms.txt`.
- **Docs: search-result excerpts fixed and search-as-you-type enabled.** Notebook
section anchors containing CSS-special characters (digit-leading `#3.-Fit-Event-Study`,
apostrophes, parentheses, colons) crashed Sphinx's search-excerpt renderer
Expand Down
7 changes: 7 additions & 0 deletions diff_diff/guides/llms.txt
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,13 @@ Full practitioner guide: call `diff_diff.get_llm_guide("practitioner")`

## Documentation

The site is organized into 5 sections, each with a landing page:
[Getting Started](https://diff-diff.readthedocs.io/en/stable/getting_started.html) ·
[Practitioner Guide](https://diff-diff.readthedocs.io/en/stable/practitioners.html) ·
[Tutorials](https://diff-diff.readthedocs.io/en/stable/tutorials/index.html) ·
[User Guide](https://diff-diff.readthedocs.io/en/stable/user_guide.html) ·
[API Reference](https://diff-diff.readthedocs.io/en/stable/api/index.html)

### Getting Started

- **Practitioner Guide** (call `diff_diff.get_llm_guide("practitioner")`): 8-step workflow for rigorous DiD analysis (Baker et al. 2025) — **start here**
Expand Down
13 changes: 13 additions & 0 deletions docs/_static/switcher.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[
{
"name": "stable",
"version": "stable",
"url": "https://diff-diff.readthedocs.io/en/stable/",
"preferred": true
},
{
"name": "latest",
"version": "latest",
"url": "https://diff-diff.readthedocs.io/en/latest/"
}
]
19 changes: 18 additions & 1 deletion docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,9 @@
"../diff_diff/guides/llms-full.txt",
"../diff_diff/guides/llms-practitioner.txt",
"../diff_diff/guides/llms-autonomous.txt",
# Overrides RTD's allow-everything default at the domain root: keeps the
# ~60 thin _modules/ source-view pages out of crawlers.
"robots.txt",
]
sitemap_url_scheme = "{link}"

Expand All @@ -129,7 +132,21 @@
"icon": "fa-brands fa-python",
},
],
"navbar_end": ["theme-switcher", "navbar-icon-links"],
"navbar_end": ["version-switcher", "theme-switcher", "navbar-icon-links"],
# Version dropdown (stable/latest). json_url points at the latest build
# so new entries propagate to every published version without rebuilds.
# ONE-SELECTOR POLICY: this navbar switcher replaces the RTD flyout
# (Settings -> Addons -> Flyout menu is disabled in the RTD dashboard,
# decided 2026-07-20) - re-enabling the flyout would put two version
# controls with different version lists on every page.
# check_switcher=False: the build-time URL probe would fail -W on CI and
# on the first RTD build (the URL only exists after this change ships);
# the switcher itself is fetched client-side at page load.
"switcher": {
"json_url": "https://diff-diff.readthedocs.io/en/latest/_static/switcher.json",
"version_match": os.environ.get("READTHEDOCS_VERSION", "latest"),
},
"check_switcher": False,
"navigation_depth": 3,
"show_toc_level": 2,
# Live-filtering search overlay. Safe to enable now that search-result
Expand Down
10 changes: 10 additions & 0 deletions docs/robots.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# Served at the domain root via conf.py html_extra_path (overrides the
# Read the Docs autogenerated robots.txt, which allows everything).
# The ~60 autogenerated _modules/ source-view pages are thin duplicates of
# the API reference - keep them out of crawlers so search engines surface
# the documented pages instead.

User-agent: *
Disallow: /en/*/_modules/

Sitemap: https://diff-diff.readthedocs.io/sitemap.xml
2 changes: 1 addition & 1 deletion docs/tutorials/08_triple_diff.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"cell_type": "markdown",
"metadata": {},
"source": [
"# Tutorial 8: Triple Difference (DDD) Estimation\n",
"# Triple Difference (DDD) Estimation\n",
"\n",
"This tutorial covers the Triple Difference (DDD) estimator, which extends standard Difference-in-Differences to settings where treatment requires satisfying two criteria.\n",
"\n",
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/18_geo_experiments.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": "t18-cell-001",
"metadata": {},
"source": [
"# Tutorial 18: Geo-Experiment Analysis with SyntheticDiD\n",
"# Geo-Experiment Analysis with SyntheticDiD\n",
"\n",
"A practitioner walkthrough for marketing analytics teams measuring lift from a campaign that ran in a subset of geographic markets. The tutorial uses `SyntheticDiD` (Arkhangelsky et al. 2021) on a simulated DMA panel and walks through the fit, the diagnostics, and the stakeholder summary you need to ship the result."
]
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/19_dcdh_marketing_pulse.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
"cell_type": "markdown",
"id": "t19-cell-001",
"metadata": {},
"source": "# Tutorial 19: dCDH for Marketing Pulse Campaigns\n\nA practitioner walkthrough for measuring lift from promotional campaigns that turn on AND off across markets at staggered times. The tutorial uses the `ChaisemartinDHaultfoeuille` estimator (alias `DCDH`) - diff-diff's estimator purpose-built for reversible (non-absorbing) treatment: the most general non-absorbing option in the library, with explicit joiner/leaver decomposition. (`LPDiD` and `TROP` also support non-absorbing treatment via their `non_absorbing` parameters, under stronger assumptions.)"
"source": "# dCDH for Marketing Pulse Campaigns\n\nA practitioner walkthrough for measuring lift from promotional campaigns that turn on AND off across markets at staggered times. The tutorial uses the `ChaisemartinDHaultfoeuille` estimator (alias `DCDH`) - diff-diff's estimator purpose-built for reversible (non-absorbing) treatment: the most general non-absorbing option in the library, with explicit joiner/leaver decomposition. (`LPDiD` and `TROP` also support non-absorbing treatment via their `non_absorbing` parameters, under stronger assumptions.)"
},
{
"cell_type": "markdown",
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/20_had_brand_campaign.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": "t20-cell-001",
"metadata": {},
"source": [
"# Tutorial 20: HAD for a National Brand Campaign with Regional Spend Intensity\n",
"# HAD for a National Brand Campaign with Regional Spend Intensity\n",
"\n",
"A practitioner walkthrough for measuring per-dollar lift when every market is treated at a different dose level - treatment varies in intensity, not in status, and no never-treated unit exists. Comparison comes from the dose variation across markets, not from an untreated holdout. The tutorial uses the `HeterogeneousAdoptionDiD` estimator (alias `HAD`), built for this case."
]
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/21_had_pretest_workflow.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": "d4e3e374",
"metadata": {},
"source": [
"# Tutorial 21: HAD Pre-test Workflow - Running the Pre-test Diagnostics on the Brand Campaign Panel\n",
"# HAD Pre-test Workflow - Running the Pre-test Diagnostics on the Brand Campaign Panel\n",
"\n",
"[Tutorial 20](20_had_brand_campaign.ipynb) fit `HeterogeneousAdoptionDiD` (HAD) on a regional brand-campaign panel and reported a per-dollar lift, with a brief visual placebo check at the end. We deliberately deferred the **formal pre-test workflow** to this tutorial, with a forward pointer in T20's \"Extensions\" section.\n",
"\n",
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/22_had_survey_design.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": "bd4f9026",
"metadata": {},
"source": [
"# Tutorial 22: Survey-Weighted HAD - The BRFSS-Shape Rollout\n",
"# Survey-Weighted HAD - The BRFSS-Shape Rollout\n",
"\n",
"The HAD series so far ran on simple iid panels. T20\n",
"(`docs/tutorials/20_had_brand_campaign.ipynb`) walked the headline workflow;\n",
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/24_staggered_vs_collapsed_power.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": "269c802e",
"metadata": {},
"source": [
"# Tutorial 24: Staggered Rollout or a Simple 2×2? A Power-Analysis Decision Guide\n",
"# Staggered Rollout or a Simple 2×2? A Power-Analysis Decision Guide\n",
"\n",
"You're running a geo experiment — a feature rolled out across the **50 US states**. The\n",
"rollout is *staggered*: a clean pre-period, then states switch on in waves over several\n",
Expand Down
2 changes: 1 addition & 1 deletion docs/tutorials/27_cic_distributional_effects.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"id": "f9b19c35",
"metadata": {},
"source": [
"# Tutorial 27: When the Average Hides the Action - Distributional DiD with Changes-in-Changes\n",
"# When the Average Hides the Action - Distributional DiD with Changes-in-Changes\n",
"\n",
"A loyalty program was rolled out to a lower-spend customer segment. Finance ran the\n",
"standard difference-in-differences on monthly spend and got a flat zero - the program\n",
Expand Down
Loading