Skip to content

config: add anchor section to align build anchors with vs code anchors#2732

Open
renejeglinsky wants to merge 4 commits into
mainfrom
rjegl/switch-anchor-behavior
Open

config: add anchor section to align build anchors with vs code anchors#2732
renejeglinsky wants to merge 4 commits into
mainfrom
rjegl/switch-anchor-behavior

Conversation

@renejeglinsky

@renejeglinsky renejeglinsky commented Jul 8, 2026

Copy link
Copy Markdown
Contributor

Previously the build replaced . in headers with -. VS Code's autocomplete just omitted/ignored the . character. With this change the anchors in VS Code a re aligned with the build result (actually the other way around)

Not working:

  • Headers with decorators, like {.property}

Comment thread .vitepress/config.js
@renejeglinsky renejeglinsky requested a review from smahati as a code owner July 8, 2026 16:27
@renejeglinsky

Copy link
Copy Markdown
Contributor Author

So the slugifier produces -req-property but the built HTML has id="-req". That means there's an explicit anchor override on those headings. Let me check:

Read events.md (lines 254-263)
No explicit #anchor override — VitePress must be handling {.property} as a class attribute on the heading, not including it in the slug. Let me check how VitePress actually processes these headings:

Bash Check how VitePress renders the -req heading in HTML
IN

Look at the raw HTML to see how VitePress renders the . req {.property} heading

grep -A2 'id="-req"' .vitepress/dist/node.js/events.html | head -5

OUT
})

Additional note about OData: For requests that are part of a changeset, the events are emitted once the entire changeset was completed. If at least one of the requests in the changeset fails, following the atomicity property ("all or nothing"), all requests fail.

cds.Request

Class cds.Request extends cds.Event with additional features to represent and deal with synchronous requests to services in event handlers, such as the query, additional request parameters, the authenticated user, and methods to send responses.

. req

Provides access to the express request object of individual requests within an incoming batch request. For convenience, in the case of non-batch requests, it points to the same request object as req.http.req.

. res

Provides access to the express response object of individual requests within an incoming batch request. For convenience, in the case of non-batch requests, it points to the same response object as req.http.res.

. method

The HTTP method of the incoming request:

msg.eventmsg.method
CREATEPOST
READGET
UPDATEPATCH
DELETEDELETE

. target

Refers to the current request's target entity definition, if any; undefined for unbound actions/functions and events. The returned definition is a linked definition as reflected from the CSN model.

For OData navigation requests along associations, msg.target refers to the last target. For example:

OData Requestreq.target
BooksAdminService.Books
Books/201/authorAdminService.Authors
Books(201)/authorAdminService.Authors

See also req.path to learn how to access full navigation paths.See Entity Definitions in the CSN reference.Learn more about linked models and definitions.

. path

Captures the full canonicalized path information of incoming requests with navigation. For requests without navigation, req.path is identical to req.target.name (or req.entity, which is a shortcut for that).

Examples based on cap/samples/bookshop AdminService:

OData Requestreq.pathreq.target.name
BooksAdminService.BooksAdminService.Books
Books/201/authorAdminService.Books/authorAdminService.Authors
Books(201)/authorAdminService.Books/authorAdminService.Authors

See also req.target

. entity

This is a convenience shortcut to msg.target.name.

. params

Provides access to parameters in URL paths as an iterable with the contents matching the positional occurrence of parameters in the url path. The respective entry is the key value pair matching the entity definition.

For example, the parameters in an HTTP request like that:

http
GET /catalog/Authors(101)/books(title='Eleonora',edition=2) HTTP/1.1

The provided parameters can be accessed as follows:

js
const [ author, book ] = req.params
// > author === { ID: 101 }
// > book === { title: 'Eleonora', edition: 2 }

. query

Captures the incoming request as a CQN query. For example, an HTTP request like GET http://.../Books is captured as follows:

js
req.query = {SELECT:{from:{ref:['Books']}}}

For bound custom operations, req.query contains the query to the entity on which the operation is called. For unbound custom operations, req.query contains an empty object.

. subject

Acts as a pointer to the instances targeted by the request. The target of a request is equivalent to the source of a query. That is, additional query options, such as CQL's .where() or OData's $filter, are not considered.

For example, for the equivalents of inbound requests, addressing single rows like these:

js
AdminService.read(Books,201)
VitePress is processing {.property} as a CSS class directive (part of the markdown-it-attrs plugin) — it strips it from the text before passing the heading text to the slugifier. So {.property} never reaches the slugifier, and the built anchor is -req not -req-property.

So the current build is actually correct — VitePress strips {.xxx} class attributes before slugifying. VS Code doesn't do that, which is the discrepancy. The link #-req is correct for the build. The user's concern about the format of the link text is separate from whether it resolves.

The issue the user is pointing out is that res](#-res)` has a backtick at the start but the closing backtick is on the next line — it looks like the link display text is malformed in the source. Let me look more carefully:

Read events.md (lines 90-94)
Line 91 is fine — req and res are valid markdown links with backtick-wrapped link text. The IDE selection just showed the line wrapped. Both anchors resolve correctly in the build (id="-req" and id="-res" exist).

To confirm the root issue: VitePress processes {.property} as a class attribute before slugifying, so the {.property} text never reaches the slugifier. This means the VS Code/VitePress behavior actually does match for these headings — both produce -req and -res. The links are correct.

The only true mismatch between VS Code anchors and VitePress anchors would be for headings that have {.xxx} and where VS Code generates a different slug than VitePress. But since VitePress strips {.xxx} before the slugifier sees it, and VS Code doesn't (it includes property in the slug), there remains a gap for those headings — but that gap existed before my change too, and the test passes with zero broken links because no existing links point to decorated-heading anchors using the VS Code format.

In short: the link on line 91 is correctly formed and resolves. The {.property} decorator issue is a VS Code vs VitePress difference that exists regardless of the slugifier change.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant