Skip to content

chore: example BFF integration#21647

Draft
npapp-dev002 wants to merge 22 commits into
developfrom
feat/CXSPA-13587
Draft

chore: example BFF integration#21647
npapp-dev002 wants to merge 22 commits into
developfrom
feat/CXSPA-13587

Conversation

@npapp-dev002

@npapp-dev002 npapp-dev002 commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Summary

This is a demo only. It shows how a Spartacus Classic storefront migrating to CCv2 can communicate with a Vivaldi BFF and through it to OCC. There is no package management, no published library, and no supported API — the code is intended as a reference for customers to follow, not as a dependency to install.

This PR is a reference implementation and documentation only. No core library changes are included — all code lives in projects/storefrontapp as a working example that customers can follow.

The implementation demonstrates how to integrate a Vivaldi BFF with Spartacus Classic using CCv2's existing meta tag substitution mechanism.

Demo app changes (storefrontapp)

  • src/index.html — adds <meta name="bff-base-url" content="BFF_BASE_URL_VALUE" /> — CCv2 replaces the placeholder at deploy time via "Connect to BFF"
  • bff/bff-base-url.token.tsInjectionToken that reads bff-base-url meta tag at Angular bootstrap; falls back to /bff/api for local dev
  • bff/bff-http.service.ts — generic HTTP client for BFF tRPC procedures (query + mutate), forwards OCC Bearer token via AuthStorageService
  • bff/examples/say-hello.component.ts — demo route /bff-say-hello calling a custom BFF procedure (sample.sayHello) with name input and x-app-custom header
  • bff/examples/occ-base-sites.component.ts — demo route /occ-base-sites calling OCC's /basesites endpoint via BFF (occ.getBaseSites procedure)
  • bff/examples/bff-example.providers.ts — lazy route provider for both demo routes, spread into app.module.ts
  • app.module.server.ts — SSR override: provides BFF_BASE_URL from process.env['BFF_BASE_URL'] (Node has no document origin for relative URLs)
  • proxy.conf.js — replaces static proxy.conf.json; reads CX_BFF_BASE_URL at dev-server startup to set the proxy target dynamically, keeping browser calls relative (/bff/api) and CORS-free
  • project.json — points serve target at proxy.conf.js
  • CX_BFF_BASE_URL wired through .env-cmdrc and environment model

Documentation

  • docs/backend-url-configuration.md — complete step-by-step guide covering every file, with full code examples, CCv2 deployment notes, and local testing instructions

Key findings from CCv2 testing

CCv2 platform URL injection

The platform's substitute-caddy.sh replaces only two placeholders:

  • OCC_BACKEND_BASE_URL_VALUE$OCC_BASE_URL (user sets via VariableSet)
  • BFF_BASE_URL_VALUE$BFF_BASE_URL (platform auto-injects /bff/ on "Connect to BFF")

OCC_BASE_URL_VALUE / occ-base-url are not supported — occ-backend-base-url remains the only OCC placeholder.

OCC URL must have a CA-signed certificate for BFF use

The BFF runs as Node.js on CCv2. Vivaldi builds the HTTPS agent as new Agent({ rejectUnauthorized: !isDev }) — locally isDev=true accepts self-signed certs, on CCv2 isDev=false rejects them. There is no per-destination TLS override in Vivaldi's API.

Consequence: OCC_BASE_URL in the BFF VariableSet must point to an OCC hostname with a CA-signed certificate (e.g. https://api.xxx.model-t.myhybris.cloud). Raw IP addresses with self-signed certs (e.g. https://40.x.x.x:9002) work in the browser (manual exception) but are rejected by the BFF container.

provideConfig() overrides meta tags

Spartacus config priority: provideConfig() > meta tag factories. Customers must remove any hardcoded backend.occ.baseUrl from their spartacus-configuration.module.ts to allow CCv2 runtime injection to work.


Test plan

  • Start BFF (vivaldi dev bff) + storefront (npm run start), navigate to /bff-say-hello — response displayed without CORS errors
  • Navigate to /occ-base-sites, click "Load Base Sites" — OCC basesites response displayed via BFF proxy
  • Build (npm run build:ssr), manually substitute BFF_BASE_URL_VALUE in dist/storefrontapp/browser/index.html, serve statically — meta tag read correctly at bootstrap
  • SSR: run with BFF_BASE_URL=https://localhost:8482/bff/api — BFF calls succeed server-side
  • CCv2 deployment: "Connect to BFF" injects /bff/ — storefront reads meta tag and calls BFF correctly

…r runtime URL injection

Extends the existing CCv2 meta-tag mechanism with two new tags so that
OCC_BASE_URL and BFF_BASE_URL can be injected at deploy time without
rebuilding or mutating built files — fixing PWA Service Worker hash
breakage and CDN cache invalidation caused by the current approach.

- Add occBaseUrlFromMetaTagFactory reading <meta name="occ-base-url">
  as a short-form alias for backend.occ.baseUrl (legacy occ-backend-base-url
  tag still supported for backward compatibility)
- Add bffServerConfigFromMetaTagFactory reading <meta name="bff-base-url">
  contributing backend.bff.baseUrl to the Spartacus config
- Extend BackendConfig with bff?: { baseUrl?: string } in OccConfig
- Add BFF_BASE_URL injection token and BffHttpService to the demo app
  as reference implementation for calling BFF tRPC procedures
- Wire CX_BFF_BASE_URL through environment model; dev-server proxy
  (proxy.conf.js) reads it to forward /bff/* to the real BFF, keeping
  browser calls relative and CORS-free
- Add docs/backend-url-configuration.md for customer guidance
@npapp-dev002 npapp-dev002 requested a review from a team as a code owner June 22, 2026 11:42
@github-actions github-actions Bot marked this pull request as draft June 22, 2026 11:42
Comment thread projects/storefrontapp/bff-proxy.mjs Dismissed
@npapp-dev002 npapp-dev002 marked this pull request as ready for review June 22, 2026 15:58
@npapp-dev002 npapp-dev002 changed the base branch from develop to release/221121.15.x June 22, 2026 16:12
@npapp-dev002 npapp-dev002 requested review from a team as code owners June 22, 2026 16:12
@cypress

cypress Bot commented Jun 22, 2026

Copy link
Copy Markdown

spartacus    Run #53729

Run Properties:  status check passed Passed #53729  •  git commit 18ddc4307e ℹ️: Merge e5769556ca31ac5b4067126c263b503ac8319cc2 into 85133b9200d36067f222928fd101...
Project spartacus
Branch Review feat/CXSPA-13587
Run status status check passed Passed #53729
Run duration 04m 09s
Commit git commit 18ddc4307e ℹ️: Merge e5769556ca31ac5b4067126c263b503ac8319cc2 into 85133b9200d36067f222928fd101...
Committer Norbert Papp
View all properties for this run ↗︎

Test results
Tests that failed  Failures 0
Tests that were flaky  Flaky 3
Tests that did not run due to a developer annotating a test with .skip  Pending 0
Tests that did not run due to a failure in a mocha hook  Skipped 0
Tests that passed  Passing 103
View all changes introduced in this branch ↗︎

@github-actions github-actions Bot marked this pull request as draft June 22, 2026 17:08
@npapp-dev002 npapp-dev002 changed the base branch from release/221121.15.x to develop June 22, 2026 18:53
…e implementation

The core library changes (new meta tag factories, BackendConfig.bff, schematics)
are not ready for release in June. Reverting them to develop baseline.

All BFF integration code remains in projects/storefrontapp as a reference
implementation documented in docs/backend-url-configuration.md. The doc
covers: index.html meta tag setup, BFF_BASE_URL token, BffHttpService,
SSR configuration, local dev proxy, and manual substitution testing.
Comment thread projects/storefrontapp/src/app/bff/bff-http.service.ts Outdated
export class BffHttpService {
protected readonly http = inject(HttpClient);
protected readonly bffBaseUrl = inject(BFF_BASE_URL);
protected readonly authStorage = inject(AuthStorageService);

@Platonn Platonn Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[NITPICK]
For simple demo purposes, AuthStorageService should be fine.
I'm curious how the automatic token renewal works in this case. Whether it works at all.
Though for first PoC it might be not crucial.

AFAIK the AuthHttpInterceptor (with its AuthHttpHeaderService) attempts to renew tokens "on the fly" whenever detected a HTTP error response about invalid token.

.query<{
message: string;
}>(
'sample.sayHello',

@Platonn Platonn Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[QUESTION]
For demo purposes, didn't we want to actually call some auto-generated OCC procedure?

To setup a Vivaldi BFF app with OCC, you need to either scaffold a fresh BFF Nx repo with OCC support - to generate its procedures and plug into the trpc router.

Or alternatively you might want to reuse existing old generated occ procedures inside spa-bff repo. You'd just need to plug them into the trpc router there:

You'd need to add to the spa-bff apps/bff/ser/api/routers/root.ts::

  export const rootRouter = router({
+   occ: {
+     v2: t.useProcedures(procedures.occ.v2),
+   },
    /*...*/

and in packages/procedures/bff/index.ts:

+  import occRouter from './occ';

export default {
+ occ: occRouter,

then you could call e.g. a procedure from the occ.v2 namespace.
I guess e.g. this on (unless I made a typo; I didn't verify it):
'occ.v2.miscs.getLanguages'
(for more, see sources of spa-bff repo)

@npapp-dev002 npapp-dev002 Jun 23, 2026

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I went with the sayHello procedure since it comes with the BFF out of the box. If we want to add an OCC call instead, I assume we'd need to document how to configure the BFF against an OCC environment. I'll look into it though.

@Platonn Platonn Jun 23, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To my understanding, Bill wanted to showcase an example integration of spa-classic with CCV2 (OCC api) through BFF. But maybe I misunderstood.
Would you mind double-checking with Gil and Bill?

What we want to showcase:
a) partial Spartacus -> BFF integration
b) full Spartacus -> BFF -> OCC integration

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I added projects/storefrontapp/src/app/bff/examples/occ-base-sites.component.ts to have an example for calling getBaseSites from occ.

Comment thread projects/storefrontapp/src/index.html Outdated
Comment thread projects/storefrontapp/src/index.html Outdated
Comment thread package.json Outdated
@npapp-dev002 npapp-dev002 changed the title feat(CXSPA-13587): Support occ-base-url and bff-base-url meta tags for runtime URL injection chore: example BFF integration Jun 23, 2026
@SAP SAP deleted a comment from github-actions Bot Jun 23, 2026
@SAP SAP deleted a comment from github-actions Bot Jun 23, 2026
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.

3 participants