Server-side fragments and client-side hydration
Document templates such as templates/pages/basic.html wrap the main reading pane in a pb-view, which later loads the actual content. To satisfy web crawlers, we already want to supply them meaningful content in the raw HTML without having to wait for pb-view. We'll therefore pre-render the content via ODD on the server using a templating function:
The function page:content (in modules/templates/page.xqm) selects the same fragment that the interactive parts API would return for the request. The resulting HTML is written into the light DOM of pb-view, which will notice that it already has content when it wakes up. It therefore avoids loading the content again and just displays what it already has available.
For human users, the experience remains the same: they can conveniently navigate the pages of the document without seeing a full page reload. However, web crawlers will collect the content by following the links given in the sitemap (see next chapter), retrieving one URL representing one fragment of the document at a time.
Because the fragment is chosen from the same id / root parameters that appear in the browser URL, every paginated address such as doc/example.xml?id=chapter-1 returns that chapter's text in the initial HTML.
Custom templates that use an xpath on pb-view (for example a source/translation column) should pass the same expression to page:content as a second argument, so the server-side fragment matches what the component would load client-side.
A text view may contain more than one pb-view, but not all of them are semantically relevant. Breadcrumbs or table of contents usually contain redundant content and don't need to be indexed by crawlers. Therefore they don't need to be pre-rendered.