Skip to content

Commit 2fcaa10

Browse files
authored
Add Netlify edge-based markdown content negotiation (#9603)
1 parent 91524e5 commit 2fcaa10

File tree

19 files changed

+1062
-12
lines changed

19 files changed

+1062
-12
lines changed

.cspell/en-words.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ emailservice
3838
EMEA
3939
erlang
4040
errorf
41+
extensionless
4142
featureflagservice
4243
flagd
4344
frauddetectionservice

content/en/search.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
---
22
title: Search Results
33
layout: search
4+
outputs: [HTML]
45
---

content/en/site/_index.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,17 +23,29 @@ Tentatively planned content organization:
2323

2424
- **About** — High-level information about the website project, including its
2525
purpose, ownership, and overall status.
26+
- **Needs, requirements, and features** — Stakeholder needs, requirements, and
27+
other relevant information broken down into features.
2628
- **Design** — Architectural design, Information Architecture (IA), layout, UX
2729
choices, theme related decisions, and other design-level artifacts.
2830
- **Implementation** — Code-level structure and conventions, Hugo/Docsy
2931
templates, SCSS/JS customizations, patches, and internal shims.
3032
- [**Build**](./build/) — Tooling, local development setup, CI/CD workflows,
3133
deployment environments, and automation details.
34+
- **Deployment** — Deployment-specific behavior for the OpenTelemetry website.
3235
- **Quality** — Link checking, accessibility standards, tests, review practices,
3336
and other quality-related processes.
3437
- **Roadmap** — Milestones, backlog, priorities, technical debt, and
3538
design/implementation decisions.
3639

40+
## Adding content
41+
42+
Keep pages short and high signal.
43+
44+
- Record decisions, rationale, constraints, and key rules.
45+
- Prefer concise summaries over long background sections.
46+
- Link to issues, plans, or code for detail instead of repeating them here.
47+
- Add only the content needed to explain how the site works and why.
48+
3749
## Site build information
3850

3951
{{% td/site-build-info/netlify "opentelemetry" %}}

content/en/site/build/npm-scripts.md

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -85,17 +85,19 @@ are internal helpers and are not intended to be run directly.
8585

8686
## Test and CI
8787

88-
| Script | Description |
89-
| -------------------------- | ----------------------------------------------------------------- |
90-
| `test` | Run the most commonly needed tests. |
91-
| `test:base` | Base tests. |
92-
| `test:all` | Run all tests: base checks plus collector-sync tests and lint. |
93-
| `test:collector-sync` | Collector-sync tests. |
94-
| `test-and-fix` | Run fix scripts (excluding i18n/refcache/submodule), then checks. |
95-
| `diff:check` | Warn if working tree has uncommitted changes. |
96-
| `diff:fail` | Fail if working tree has changes (e.g. after build). |
97-
| `netlify-build:preview` | `build:preview` then `diff:check`. |
98-
| `netlify-build:production` | `build:production` then `diff:check`. |
88+
| Script | Description |
89+
| -------------------------- | ------------------------------------------------------------------- |
90+
| `test` | Run the most commonly needed tests. |
91+
| `test:base` | Base tests. |
92+
| `test:all` | Runs `test:base`, `test:collector-sync`, and `test:edge-functions`. |
93+
| `test:collector-sync` | Collector-sync tests. |
94+
| `test:edge-functions` | Node test runner over `netlify/edge-functions/**/*.test.ts`. |
95+
| `test:edge-functions:live` | Optional `node:test` live suite; supports `--help`. |
96+
| `test-and-fix` | Run fix scripts (excluding i18n/refcache/submodule), then checks. |
97+
| `diff:check` | Warn if working tree has uncommitted changes. |
98+
| `diff:fail` | Fail if working tree has changes (e.g. after build). |
99+
| `netlify-build:preview` | `build:preview` then `diff:check`. |
100+
| `netlify-build:production` | `build:production` then `diff:check`. |
99101

100102
## Utilities
101103

content/en/site/design/_index.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
---
2+
title: Design
3+
description: >-
4+
Architectural to lower-level design documentation for the OpenTelemetry
5+
website.
6+
weight: 30
7+
---
8+
9+
This section records design decisions for the OpenTelemetry website.
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
---
2+
title: Agent support
3+
description: >-
4+
Design notes for making OpenTelemetry website content easier for agents to
5+
consume.
6+
weight: 10
7+
---
8+
9+
Design notes for the broader [agent-friendly content delivery](/site/features/)
10+
feature.
11+
12+
## Markdown content negotiation
13+
14+
Use a Netlify Edge Function to serve Hugo's prebuilt `index.md` output when a
15+
request explicitly asks for or prefers `text/markdown`.
16+
17+
### Rationale
18+
19+
- Not every HTML page should have a Markdown equivalent.
20+
- HTTP negotiation belongs at the delivery layer.
21+
- The function can fall back to normal HTML when no Markdown artifact exists.
22+
23+
### Rules
24+
25+
- Only `GET` and `HEAD` are considered.
26+
- Requests for `.md` and other non-page resources bypass negotiation.
27+
- Page-like requests include:
28+
- slash paths
29+
- extensionless paths
30+
- `.../index.html` paths
31+
- Markdown is served when `text/markdown` is accepted with `q` greater than zero
32+
and its `q` is **greater than or equal to** the highest `q` for `text/html` /
33+
`application/xhtml+xml` (equal weights choose Markdown).
34+
- Wildcards such as `*/*` are ignored by design: only explicit markdown/html
35+
media types contribute q-values. This is a conservative choice that may be
36+
revisited later.
37+
- Missing Markdown falls back to the normal HTML response.
38+
- Negotiated responses set `Vary: Accept`.
39+
- `/search/` emits only HTML and therefore always falls back to HTML.
40+
41+
A note on path mapping:
42+
43+
- Pretty URLs like `/docs/` map to Hugo's `/docs/index.md` output;
44+
- `index.html` maps to the sibling `.md` file (for example `/docs/index.html`
45+
`/docs/index.md`).
46+
- Other `.html` paths are left to Netlify's normal redirects and routing: e.g.,
47+
Netlify redirects `/docs.html` to `/docs/`.
48+
49+
### Related implementation
50+
51+
- `config/_default/hugo.yaml` enables Markdown outputs for this site.
52+
- `content/en/search.md` opts the search page out with `outputs: [HTML]`.
53+
- `netlify.toml` wires the Edge Function ahead of other route handling.
54+
- `netlify/edge-functions/markdown-negotiation/index.ts` implements negotiation;
55+
`netlify/edge-functions/markdown-negotiation.ts` is the Netlify entry stub
56+
that re-exports it.

content/en/site/features.md

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
---
2+
title: Features
3+
description: >-
4+
Brief summaries of notable site features with links to their primary
5+
references.
6+
weight: 20
7+
cSpell:ignore: docsy
8+
---
9+
10+
## Agent-friendly content delivery
11+
12+
Make site content easier for agents to discover and consume. Current work adds
13+
Markdown output for content pages and HTTP negotiation for
14+
`Accept: text/markdown`.
15+
16+
- Status: in progress
17+
- Design: [Agent support](../design/agent-support/)
18+
- Implementation: under `netlify/edge-functions/markdown-negotiation.ts` with
19+
folder for logic and tests.
20+
- References:
21+
[opentelemetry.io#9449](https://github.com/open-telemetry/opentelemetry.io/issues/9449),
22+
[docsy#2596](https://github.com/google/docsy/issues/2596)

netlify.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@ from = "https://blog.opentelemetry.io/*"
1515
to = "https://opentelemetry.io/blog/:splat"
1616
force = true
1717

18+
[[edge_functions]]
19+
function = "markdown-negotiation"
20+
path = "/*"
21+
1822
[[edge_functions]]
1923
function = "schema-analytics"
2024
path = "/schemas/*"
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export { default } from './markdown-negotiation/index.ts';
2+
export * from './markdown-negotiation/index.ts';
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# Markdown Negotiation
2+
3+
This folder contains the markdown-negotiation Edge Function implementation and
4+
its tests.
5+
6+
The local `package.json` sets `"type": "module"` so Node treats the `.ts` test
7+
files in this folder as ESM without changing module semantics for the whole
8+
repo.
9+
10+
## Unit tests
11+
12+
Run the unit tests with:
13+
14+
```console
15+
npm run test:edge-functions
16+
```
17+
18+
### Live tests
19+
20+
To run the live checks over a server run the `test:edge-functions:live` NPM
21+
script. For usage information:
22+
23+
```console
24+
npm run test:edge-functions:live -- --help
25+
```
26+
27+
Live tests use Node’s built-in **`node:test`** runner in
28+
[`live-check.test.mjs`](./live-check.test.mjs). They are **not** picked up by
29+
`npm run test:edge-functions`, which only runs `**/*.test.ts`.

0 commit comments

Comments
 (0)