Skip to content

Evaluate in the context of the originating page - #11

Merged
marcospassos merged 7 commits into
masterfrom
page-context
Aug 17, 2026
Merged

marcospassos merged 7 commits into
masterfrom
page-context

Conversation

@marcospassos

@marcospassos marcospassos commented Aug 17, 2026 •

Copy link
Copy Markdown
Member

Problem

evaluate() and fetchContent() built context.page from the URL of the request being handled. For calls coming from useContent, useEvaluation, Slot and Personalization, that request is the internal API route, so every evaluation was contextualized as /api/_croct/* instead of the page. The referrer was wrong in the browser too, as the fetch sends the page itself as Referer.

Solution

The page is provided by whoever knows it, and the SDK assembles the context with EvaluationContext.createPageContext (croct-tech/sdk-js#527, released in @croct/sdk@0.22.3):

  • In the browser, the SDK captures the page it runs on — URL, title, referrer and time zone — through the configured urlSanitizer.
  • While rendering on the server, the page is the request being rendered. Title and time zone are absent: the page is not rendered yet, and the time zone of the server is not the time zone of the user.
  • In the server composables, the context provided by the caller takes precedence, and the page of the request remains the fallback for direct calls in application routes.

Requests still go through the internal routes with the API key, the server-issued token, the preview token and per-tenant credentials, so nothing changes for applications.

Also fixed

  • evaluate() discarded a context provided by the caller, and fetchContent() dropped the page of the request when the caller provided a partial one.
  • The attributes prop of Slot and Personalization was sent as a top-level option, which the server API ignores, so it never reached the evaluation. It now travels as context.attributes.
  • Direct fetchContent() and evaluate() calls in application routes now report a sanitized page.

Testing

Unit tests cover the context resolution, the composables and the components. The e2e run against a mock API that echoes the received context, covering server rendering, client navigation, refetching in the browser, and direct calls in application routes.

Mutation testing over the changed code killed all 17 mutants, including spread precedence, environment detection, referrer source, sanitizer and page fallback.

109 unit tests, 60 e2e, 3 prerendering.

Content and queries were evaluated in the context of the request being
handled, which is the internal API route rather than the page that
originated the fetch, so every evaluation reported `/api/_croct/*` as
the page.

The composables and the components now report the page they run on: the
page being rendered on the server, or the page open in the browser,
including its title and time zone. The server composables give the
reported context precedence over the one derived from the request,
which remains the fallback for direct calls.

As a result, the `attributes` of the components now reach the API as
part of the context, instead of being dropped as an unknown option.
@pkg-pr-new

pkg-pr-new Bot commented Aug 17, 2026 •

Copy link
Copy Markdown

Open in StackBlitz

npm i https://pkg.pr.new/@croct/plug-nuxt@11

commit: e91fccc

The evaluation context is small enough to be assembled where it is used,
so the helpers give way to the object literals they wrapped, leaving a
single module for the context reported by the composables.

The URI and the referrer of the request are now sanitized as configured,
which requires exposing the client options to the server bundle.
The SDK captures the page it runs on and assembles the context, so the
module only decides where the page comes from: the request being rendered
on the server, or the tab in the browser.

The sanitizer moves back out of the middleware, as the context is now
sanitized where it is built, keeping the request context untouched.
@marcospassos marcospassos added the bug Something isn't working label Aug 17, 2026
@marcospassos
marcospassos merged commit 40784fc into master Aug 17, 2026
8 of 9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant