-
Notifications
You must be signed in to change notification settings - Fork 2
feat(web-sdk_angular): Web SDK + Angular reference implementation [NT-3465] #316
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
David Nalchevanidze (nalchevanidze)
wants to merge
204
commits into
main
Choose a base branch
from
NT-3235
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
204 commits
Select commit
Hold shift + click to select a range
3fff549
feat(implementations): scaffold Angular Web SDK reference implementation
nalchevanidze 00b4e71
chore(implementations): remove premature angular-web-sdk root shortcu…
nalchevanidze 0992f18
docs(angular-web-sdk): remove project structure section from README
nalchevanidze 3a57bc5
chore(implementations): remove angular-web-sdk launch script
nalchevanidze 8d507f0
docs(angular-web-sdk): add REQUIREMENTS.md with acceptance criteria
nalchevanidze 4952282
feat(angular-web-sdk): scaffold app shell and config token
nalchevanidze 25e996a
chore(angular-web-sdk): drop Angular role suffixes from files and cla…
nalchevanidze 76b7692
chore(angular-web-sdk): add global styles and active nav highlighting
nalchevanidze bbe66a2
feat(angular-web-sdk): SDK initialisation and page tracking
nalchevanidze 8e1a08e
feat(angular-web-sdk): Contentful CDA client with locale consistency …
nalchevanidze dcd3312
feat(angular-web-sdk): entry resolution, auto/manual tracking, click …
nalchevanidze 84d5937
chore(angular-web-sdk): improve page layout, spacing, and variant vis…
nalchevanidze 8589f16
feat(angular-web-sdk): consent toggle UI and SDK wiring (feature 7)
nalchevanidze 91b7fcf
feat(angular-web-sdk): identify/reset UI and SDK wiring (feature 8)
nalchevanidze 4310b3a
feat(angular-web-sdk): live updates global toggle and per-entry overr…
nalchevanidze 1a6b955
chore(angular-web-sdk): mark features 9-10 done in REQUIREMENTS.md
nalchevanidze a10139c
feat(angular-web-sdk): multi-route PageTwo and shared ControlPanel (f…
nalchevanidze 1dfea8f
chore(angular-web-sdk): mark feature 17 done in REQUIREMENTS.md
nalchevanidze 402e801
feat(angular-web-sdk): analytics event display in persistent sidebar …
nalchevanidze dfa684e
chore(angular-web-sdk): mark feature 15 done in REQUIREMENTS.md
nalchevanidze e15b5da
chore(angular-web-sdk): move analytics sidebar to left, fix grid layout
nalchevanidze a37664e
feat(angular-web-sdk): feature flag subscription with auto-tracked vi…
nalchevanidze df2cf6f
chore(angular-web-sdk): mark feature 19 done in REQUIREMENTS.md
nalchevanidze 75ad649
docs(angular-web-sdk): add visual verification steps for feature 19 i…
nalchevanidze 7aa34ad
docs(angular-web-sdk): simplify feature 19 verification steps
nalchevanidze 88bd7d8
feat(angular-web-sdk): rich text rendering, merge tags, and card layo…
nalchevanidze 716a2e8
feat(angular-web-sdk): nested entries recursive resolution (feature 12)
nalchevanidze fd3e53d
feat(angular-web-sdk): preview panel lazy-load and live-all-entries (…
nalchevanidze 68bb906
docs(angular-web-sdk): strip progress table and env vars from REQUIRE…
nalchevanidze b5dc30d
docs(angular-web-sdk): add visual verification steps to all requirements
nalchevanidze bba7cab
feat(angular-web-sdk): toggle Identify/Reset button based on identifi…
nalchevanidze 61bdb5b
docs(angular-web-sdk): fix requirements soundness issues from audit
nalchevanidze bc37e9a
feat(angular-web-sdk): remove redundant event type from analytics eve…
nalchevanidze 82223b6
feat(angular-web-sdk): prefix entry IDs with 'id:' in analytics event…
nalchevanidze 07412e6
feat(angular-web-sdk): prefix page URL with 'url:' in analytics event…
nalchevanidze 6f084a2
chore(angular-web-sdk): remove blue left border from section headers
nalchevanidze 2c54e7c
fix(angular-web-sdk): hide zero duration from analytics event labels
nalchevanidze 1ad2a8f
fix(angular-web-sdk): always prefix componentId with 'id:' in event l…
nalchevanidze ba5a497
feat(angular-web-sdk): inline stat+button rows in control panel
nalchevanidze 60b2cab
feat(angular-web-sdk): control panel table layout, port 4200, updated…
nalchevanidze 49c66e5
feat(angular-web-sdk): control panel and UI polish
nalchevanidze 190064e
chore(angular-web-sdk): rename Raw to Raw Events to match React imple…
nalchevanidze 7d9ef00
chore(angular-web-sdk): rename Events to Unique Events in analytics d…
nalchevanidze 4fbba75
chore(angular-web-sdk): rename event counters to Unique/Total
nalchevanidze 32ecdf5
chore(angular-web-sdk): move Live updates section to first column on …
nalchevanidze 5a42f44
chore(angular-web-sdk): increase spacing between SDK panel and conten…
nalchevanidze 9a1eb00
chore(angular-web-sdk): fix section spacing via display:contents on p…
nalchevanidze cb5a8ac
refactor(angular-web-sdk): consolidate selectedOptimizations and shar…
nalchevanidze cb9bdcc
refactor(angular-web-sdk): extract Angular SDK integration layer to s…
nalchevanidze f321072
refactor(angular-web-sdk): make sdk/ fully generic with no app/ imports
nalchevanidze 8d7108e
refactor(angular-web-sdk): rename SDK classes to Ng-prefixed convention
nalchevanidze 2205886
refactor(angular-web-sdk): move ContentfulClient into sdk/ as NgConte…
nalchevanidze 1ee547a
refactor(angular-web-sdk): organise sdk/ into services/ and utils/ su…
nalchevanidze 9ae6a00
refactor(angular-web-sdk): extract resolveWithMeta and NgContentfulLi…
nalchevanidze 694fda1
fix(angular-web-sdk): restore globalLiveUpdates property name on NgCo…
nalchevanidze 57b1169
fix(angular-web-sdk): fix sed-mangled method name and meta nullabilit…
nalchevanidze 3345c49
refactor(angular-web-sdk): replace individual computed signals with @…
nalchevanidze f6de14f
refactor(angular-web-sdk): replace individual computed signals with @…
nalchevanidze 047b83e
refactor(angular-web-sdk): inline toggle call and privatize selectedO…
nalchevanidze aa0e6ee
refactor(angular-web-sdk): simplify control-panel signals by collapsi…
nalchevanidze c36d8d0
refactor(angular-web-sdk): move sections into components and remove u…
nalchevanidze 5c0ee57
refactor(angular-web-sdk): collapse trackArrival wrapper and use arro…
nalchevanidze d155d31
refactor(angular-web-sdk): extract ContentCard, move config/utils, ap…
nalchevanidze 11d5ce2
refactor(angular-web-sdk): inline type guards, import isRecord from S…
nalchevanidze eb892c3
refactor(angular-web-sdk): consolidate entry IDs into ENTRIES config …
nalchevanidze 699b316
fix(angular-web-sdk): move sidebar before main so it renders on the left
nalchevanidze 7a27667
chore(angular-web-sdk): remove redundant live-updates subtitle and ne…
nalchevanidze 237287d
refactor(angular-web-sdk): unique/raw toggle buttons, precompute even…
nalchevanidze c27bdad
refactor(angular-web-sdk): inline NestedContentEntry into ContentCard…
nalchevanidze 21e03b4
refactor(angular-web-sdk): consolidate content-card folder and add in…
nalchevanidze 8f7ad43
refactor(angular-web-sdk): move rich-text-renderer into content-card …
nalchevanidze e7bbf7c
refactor(angular-web-sdk): rename components, consolidate content-car…
nalchevanidze 8965c14
refactor(angular-web-sdk): expose selectedOptimizations signal on ser…
nalchevanidze fc2a321
refactor(angular-web-sdk): default resolveWithMeta to global selected…
nalchevanidze e37df22
refactor(angular-web-sdk): move all live-entry logic into NgContentfu…
nalchevanidze 91709be
refactor(angular-web-sdk): make preview panel selectors configurable,…
nalchevanidze ea7b43f
refactor(angular-web-sdk): use _ convention for unused inject and rem…
nalchevanidze 93a03f5
fix(angular-web-sdk): call inject in constructor to avoid TS6133 on u…
nalchevanidze b799ab1
refactor(angular-web-sdk): rename analytics-event-display to event-log
nalchevanidze dad44b8
refactor(angular-web-sdk): compute badges array in model, render with…
nalchevanidze d2fe271
style(angular-web-sdk): reduce badge size and gap
nalchevanidze e625eb8
refactor(angular-web-sdk): extract EntryBadge component with CSS tool…
nalchevanidze 23e9e62
refactor(angular-web-sdk): consolidate Badge type and builders into b…
nalchevanidze 7e8b426
refactor(angular-web-sdk): extract ObservationMode type from sdk
nalchevanidze 82a7f09
refactor(angular-web-sdk): add resolveWith to resolver, collapse Nest…
nalchevanidze 6a08cd6
refactor(angular-web-sdk): unify inject pattern with .with() on both …
nalchevanidze c217e2d
refactor(angular-web-sdk): merge NgContentfulLiveEntry and resolver i…
nalchevanidze c32a262
refactor(angular-web-sdk): consolidate isMergeTagEntry to utils, rena…
nalchevanidze b442a73
refactor(angular-web-sdk): type profile$ with Zod, expose profile sig…
nalchevanidze 50bd5e2
refactor(angular-web-sdk): delete NgContentfulLiveEntry, move Observa…
nalchevanidze f0f90df
refactor(angular-web-sdk): flatten sdk/utils/ to utils.ts, trim SDK p…
nalchevanidze 0827223
feat(angular-web-sdk): add provideContentfulOptimizationConfig helper
nalchevanidze 7b53aa2
refactor(angular-web-sdk): provideContentfulOptimizationConfig takes …
nalchevanidze bfa3905
refactor(angular-web-sdk): remove NG_CONTENTFUL_OPTIMIZATION_CONFIG f…
nalchevanidze 7cd1f9f
refactor(angular-web-sdk): remove MergeTagPipe and NgContentfulOptimi…
nalchevanidze 2e37918
refactor(angular-web-sdk): remove CONFIG token, inline env vars into …
nalchevanidze aff6a8d
refactor(angular-web-sdk): rename config/entries.ts to fixtures.ts, E…
nalchevanidze c186c92
fix(angular-web-sdk): access import.meta.env directly instead of dest…
nalchevanidze 6d78afd
refactor(angular-web-sdk): replace OnInit/OnDestroy subscription with…
nalchevanidze 6c16e20
refactor(angular-web-sdk): hide NgContentfulOptimizationResolver, exp…
nalchevanidze 7bea74d
refactor(angular-web-sdk): make sdk non-optional, remove all undefine…
nalchevanidze 393af8e
refactor(angular-web-sdk): remove sdk proxy methods, tighten service …
nalchevanidze 8591b4d
refactor(angular-web-sdk): replace OnInit+signals with resource() for…
nalchevanidze 0af5c4c
fix(angular-web-sdk): expose clickScenarios as field for template access
nalchevanidze 7761a43
refactor(angular-web-sdk): add FIXTURES.pageTwo.ids, use it in resour…
nalchevanidze 44c741c
fix(angular-web-sdk): bind trackConversion as arrow field, remove loa…
nalchevanidze 6bc98be
refactor(angular-web-sdk): delete unused MergeTagPipe
nalchevanidze 31ad43d
refactor(angular-web-sdk): inline NgContentfulOptimizationResolver in…
nalchevanidze a459216
refactor(angular-web-sdk): move NgContentfulLiveUpdates to app layer
nalchevanidze 8e98941
refactor(angular-web-sdk): move NgContentfulLiveUpdates into app/serv…
nalchevanidze 271efe8
refactor(angular-web-sdk): remove NgContentfulLiveUpdates from NgCont…
nalchevanidze 95a21a5
docs(angular-web-sdk): shorten and de-angularize REQUIREMENTS.md
nalchevanidze 271afdd
Merge branch 'main' into NT-3348
nalchevanidze 4bdfd3b
feat(angular-web-sdk): add descriptions to live-updates section cards
nalchevanidze 229e28d
docs(angular-web-sdk): update REQUIREMENTS and add jira ticket
nalchevanidze 65b79cf
feat(angular-web-sdk): implement SDK teardown in NgContentfulOptimiza…
nalchevanidze fa2bff7
docs(angular-web-sdk): resolve remaining REQUIREMENTS TODOs
nalchevanidze 007f1d3
docs(angular-web-sdk): rewrite REQUIREMENTS as dense categorised sect…
nalchevanidze 02c5a70
docs(angular-web-sdk): reformat REQUIREMENTS as bullet lists with inl…
nalchevanidze 86cfdbd
docs(angular-web-sdk): move entry resolution under content, clarify p…
nalchevanidze 047c92e
docs(angular-web-sdk): simplify entry resolution requirement
nalchevanidze 3562fa7
fix(angular-web-sdk): prevent locked entries from re-resolving on sel…
nalchevanidze f92b333
refactor(angular-web-sdk): simplify NgContentfulEntry signal wiring a…
nalchevanidze f421ba2
refactor(angular-web-sdk): simplify NgContentfulEntry — inline resolv…
nalchevanidze c75cc7e
refactor(angular-web-sdk): unify entry and rich text resolution, add …
nalchevanidze 2152ca3
refactor(angular-web-sdk): replace EntryMeta tags set with mergeTagRe…
nalchevanidze 7f4258c
refactor(angular-web-sdk): remove nested badge, inline variant badge …
nalchevanidze 454be77
refactor(angular-web-sdk): collapse content-card into a single recurs…
nalchevanidze 8e0948c
refactor(angular-web-sdk): normalize component conventions
nalchevanidze 271f917
feat(angular-web-sdk): add live mode badge to content card
nalchevanidze 20be148
refactor(angular-web-sdk): replace procedural badge building with BAD…
nalchevanidze 441bfd0
refactor(angular-web-sdk): extract liveModeKey to match mergeTagKey p…
nalchevanidze 2d09270
refactor(angular-web-sdk): inline buildBadges into badges computed
nalchevanidze df4a84a
style(angular-web-sdk): use purple for always-live badge
nalchevanidze 8e8fb29
refactor(angular-web-sdk): remove richtext badge
nalchevanidze fd29b45
refactor(angular-web-sdk): simplify and deduplicate SDK internals
nalchevanidze 7fe1a25
refactor(angular-web-sdk): use ReturnType<typeof createClient> instea…
nalchevanidze 4156ec9
refactor(angular-web-sdk): use ContentfulClientApi<undefined> instead…
nalchevanidze 293de91
refactor(angular-web-sdk): remove selectedOptimizations input from Co…
nalchevanidze 1324d8e
refactor(angular-web-sdk): clean up SDK internals and remove RxJS fro…
nalchevanidze 25bea50
feat(angular-web-sdk): style merge tag badge by resolved state
nalchevanidze c73fc13
refactor(angular-web-sdk): clean up merge tag resolution in NgContent…
nalchevanidze 76d7330
refactor(angular-web-sdk): fold baselineId/resolvedId into EntryMeta
nalchevanidze 7eec044
refactor(angular-web-sdk): unify meta generation and extract liveRead…
nalchevanidze 5d70082
feat(angular-web-sdk): move template logic to computed signals and un…
nalchevanidze eabd5cf
refactor(angular-web-sdk): remove redundant section labels and descri…
nalchevanidze 337de9d
feat(angular-web-sdk): add SDK state tooltips and unify badge/tooltip…
nalchevanidze 0648e0c
feat(angular-web-sdk): improve badge labels with icons and consistent…
nalchevanidze add8237
refactor(angular-web-sdk): dissolve src/sdk/ into src/app/
nalchevanidze d2b6c06
refactor(angular-web-sdk): move ContentfulEntry types into contentful…
nalchevanidze bbe416f
chore(angular-web-sdk): address PR review feedback
nalchevanidze e9fba96
chore(angular-web-sdk): update naming and README
nalchevanidze bf562af
refactor(angular-web-sdk): switch event log to table layout with time…
nalchevanidze f38d182
refactor(angular-web-sdk): rename Analytics Events panel to Tracking
nalchevanidze d5e77cf
fix(angular-web-sdk): deduplicate and label identify events in tracki…
nalchevanidze afdd0a1
fix(angular-web-sdk): show userId as label for identify events in tra…
nalchevanidze 3b10a47
feat(angular-web-sdk): add ENTRY_NAMES map, show names in cards and t…
nalchevanidze a50dd1a
feat(angular-web-sdk): add NgEntryRegistry to resolve variant IDs to …
nalchevanidze 43543dd
refactor(angular-web-sdk): always show last 5 chars of ID alongside n…
nalchevanidze 16114ce
revert(angular-web-sdk): remove ENTRY_NAMES map and NgEntryRegistry
nalchevanidze 3c080ec
refactor(angular-web-sdk): truncate component IDs to last 5 chars in …
nalchevanidze ca2ce99
refactor(angular-web-sdk): show first 5 chars of component ID in trac…
nalchevanidze 37e3f21
refactor(angular-web-sdk): uppercase truncated component ID in tracki…
nalchevanidze 36a9ab4
refactor(angular-web-sdk): show full component ID in event log label
nalchevanidze 0c41995
refactor(angular-web-sdk): preserve original casing of component ID i…
nalchevanidze 6137737
refactor(angular-web-sdk): simplify event log by deriving label/testI…
nalchevanidze 68e59c4
refactor(angular-web-sdk): replace event list with Map and sort by da…
nalchevanidze dbb7e4f
refactor(angular-web-sdk): store typeLabel on event and clean up temp…
nalchevanidze af02cb5
refactor(angular-web-sdk): convert event type label and rename label …
nalchevanidze 758babb
refactor(angular-web-sdk): update event log component
nalchevanidze e060727
refactor(angular-web-sdk): differentiate component view vs comp by vi…
nalchevanidze 38b5539
refactor(angular-web-sdk): keep componentId as value for component ev…
nalchevanidze 9c5c19a
refactor(angular-web-sdk): rename trigger custom event button to trig…
nalchevanidze 25c4189
refactor(angular-web-sdk): update button label to trigger custom view…
nalchevanidze b534ca5
refactor(web-sdk_angular): rename angular-web-sdk to web-sdk_angular
nalchevanidze b2482d5
Merge branch 'main' into NT-3235
nalchevanidze 4c3cd2c
refactor(web-sdk_angular): adapt to locale simplification breaking ch…
nalchevanidze 00708c4
refactor(web-sdk_angular): move resource() wrapping into NgContentful…
nalchevanidze 0a06e89
chore: bump .nvmrc to 24.15.0 for Angular 22 compatibility
nalchevanidze c7044af
refactor(web-sdk_angular): simplify isLive override resolution with ??
nalchevanidze 4dd2e87
refactor(web-sdk_angular): rename event-log component to tracking
nalchevanidze 1a107c7
chore(web-sdk_angular): remove stale REQUIREMENTS.md reference from A…
nalchevanidze 9731ece
great push
nalchevanidze bd0e4f6
refactor(web-sdk_angular): split global CSS into per-component SCSS f…
nalchevanidze ef97ebd
fix(web-sdk_angular): add styleUrl to Badge and control-panel components
nalchevanidze 95cbe68
refactor(web-sdk_angular): rename ContentCard→EntryCard, scope CSS cl…
nalchevanidze 13306a1
refactor(web-sdk_angular): apply AGENTS.md class member ordering to c…
nalchevanidze b087487
refactor(web-sdk_angular): rename Tracking component to TrackingLog
nalchevanidze d9d7db6
refactor(web-sdk_angular): inline generateMeta and simplify mergeTagR…
nalchevanidze 24d6438
refactor(web-sdk_angular): type rich text nodes with proper types fro…
nalchevanidze 406d6ff
refactor(web-sdk_angular): simplify rich text merge tag resolution
nalchevanidze 24c0094
refactor(web-sdk_angular): move isMergeTagEntry from utils into entry…
nalchevanidze 07f7476
refactor(web-sdk_angular): merge EntryMeta into ResolvedEntryView
nalchevanidze 00d55f6
refactor(web-sdk_angular): replace NgContentfulEntry class with injec…
nalchevanidze d607d93
refactor(web-sdk_angular): apply class member ordering and rename liv…
nalchevanidze e6b04ca
refactor(web-sdk_angular): reuse isMergeTagEntry from sdk and remove …
nalchevanidze 422f7f3
refactor(web-sdk_angular): extract setupManualTracking, rename Resolv…
nalchevanidze d998370
refactor(web-sdk_angular): replace ObservationMode with manualTrackin…
nalchevanidze bcb5b44
refactor(web-sdk_angular): remove redundant active flag in setupManua…
nalchevanidze 8c6cce2
refactor(web-sdk_angular): extract track/clear helpers and simplify e…
nalchevanidze aea6706
refactor(web-sdk_angular): replace observation mode with manualTracki…
nalchevanidze 97c7d59
refactor(web-sdk_angular): remove isAuto and use manualTracking direc…
nalchevanidze dc728e6
refactor(web-sdk_angular): remove mod field from BADGE_MAP, use key a…
nalchevanidze b9d05e4
fix(web-sdk_angular): correct template field names resolvedId→entryId…
nalchevanidze File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1 +1 @@ | ||
| 24.13.0 | ||
| 24.15.0 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,15 @@ | ||
| DOTENV_CONFIG_QUIET=true | ||
|
|
||
| PUBLIC_NINETAILED_CLIENT_ID="mock-client-id" | ||
| PUBLIC_NINETAILED_ENVIRONMENT="main" | ||
|
|
||
| PUBLIC_EXPERIENCE_API_BASE_URL="http://localhost:8000/experience/" | ||
| PUBLIC_INSIGHTS_API_BASE_URL="http://localhost:8000/insights/" | ||
|
|
||
| PUBLIC_CONTENTFUL_TOKEN="mock-token" | ||
| PUBLIC_CONTENTFUL_ENVIRONMENT="master" | ||
| PUBLIC_CONTENTFUL_SPACE_ID="mock-space-id" | ||
|
|
||
| PUBLIC_CONTENTFUL_CDA_HOST="localhost:8000" | ||
| PUBLIC_CONTENTFUL_BASE_PATH="contentful" | ||
| PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL="true" |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,23 @@ | ||
| # dependencies | ||
| node_modules/ | ||
|
|
||
| # build output | ||
| dist/ | ||
|
|
||
| # Angular cache | ||
| .angular/ | ||
|
|
||
| # env files (copy from .env.example to set up locally) | ||
| .env | ||
| .env*.local | ||
|
|
||
| # logs produced by launch-reference-app.sh | ||
| logs/ | ||
|
|
||
| # debug | ||
| *.log | ||
| .pnpm-debug.log* | ||
|
|
||
| # misc | ||
| .DS_Store | ||
| *.tsbuildinfo |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,41 @@ | ||
| # AGENTS.md | ||
|
|
||
| Angular SPA reference implementation of `@contentful/optimization-web`. Serves the app on | ||
| `http://localhost:4200` via the Angular CLI dev server alongside the shared mock API server. | ||
|
|
||
| ## Rules | ||
|
|
||
| - Do not add local adapter shims; import SDK behaviour directly from the published package surface | ||
| when it exists. | ||
| - This implementation uses Angular CLI (`@angular/build`) and PM2-managed mock server processes. | ||
| - Use standalone components (no NgModule). | ||
| - Use modern Angular patterns: signals and `computed()` for state, `inject()` for dependency | ||
| injection (not constructor injection), `input()` / `output()` for component I/O, `toSignal()` to | ||
| bridge RxJS observables to templates, and `@if` / `@for` control flow syntax. | ||
| - Name files and classes after the concept only — no Angular-role suffixes anywhere. File: `home.ts` | ||
| not `home.component.ts`. Class: `Home` not `HomeComponent`, `Optimization` not | ||
| `OptimizationService`, `MergeTag` not `MergeTagPipe`, etc. | ||
| - Avoid unsafe type assertions (`as SomeType`). Use `isRecord()` and typed type-guard functions | ||
| instead. The `no-unsafe-type-assertion` ESLint rule is enforced and blocks commits. | ||
| - Use explicit named types instead of `ReturnType<typeof ...>` inference. Prefer the actual type | ||
| (e.g. `Signal<Foo>`, `ContentfulClientApi<undefined>`) over derived magic types. | ||
| - Follow the Angular style guide class member ordering: inputs → injected dependencies → private | ||
| state → constructor (effects/setup) → protected state (template-facing computed/signals) → | ||
| lifecycle hooks → public methods → private methods. | ||
|
|
||
| ## Commands | ||
|
|
||
| ```sh | ||
| pnpm implementation:run -- web-sdk_angular implementation:install | ||
| pnpm implementation:run -- web-sdk_angular serve:mocks | ||
| pnpm implementation:run -- web-sdk_angular dev | ||
| pnpm implementation:run -- web-sdk_angular build | ||
| pnpm implementation:run -- web-sdk_angular typecheck | ||
| ``` | ||
|
|
||
| ## Validate | ||
|
|
||
| - Run `typecheck` for TypeScript changes. | ||
| - Run `build` for production bundling changes. | ||
| - Run lint via `npx eslint <file>` from the implementation directory for source file changes. | ||
| - The pre-commit hook runs lint and Prettier automatically — fix any errors before committing. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
| <p align="center"> | ||
| <a href="https://www.contentful.com/developers/docs/personalization/"> | ||
| <img alt="Contentful Logo" title="Contentful" src="../../contentful-icon.png" width="150"> | ||
| </a> | ||
| </p> | ||
|
|
||
| <h1 align="center">Contentful Personalization & Analytics</h1> | ||
|
|
||
| <h3 align="center">Web SDK + Angular Reference Implementation</h3> | ||
|
|
||
| <div align="center"> | ||
|
|
||
| [Guides](https://contentful.github.io/optimization/documents/Documentation.Guides.html) · | ||
| [Reference](https://contentful.github.io/optimization) · [Contributing](../../CONTRIBUTING.md) | ||
|
|
||
| </div> | ||
|
|
||
| > [!WARNING] | ||
| > | ||
| > The Optimization SDK Suite is pre-release (alpha). Breaking changes can be published at any time. | ||
|
|
||
| Reference implementation of `@contentful/optimization-web` for Angular applications. Demonstrates | ||
| all SDK integration patterns — entry resolution, auto and manual tracking, consent, identify/reset, | ||
| live updates, nested entries, rich text with merge tags, feature flags, analytics event display, and | ||
| the preview panel. | ||
|
|
||
| ## What this demonstrates | ||
|
|
||
| - SDK initialisation as a singleton Angular service | ||
| - Page tracking on every route change via the Angular router | ||
| - Entry resolution with variant/baseline display | ||
| - Auto-tracking via `data-ctfl-*` DOM attributes | ||
| - Manual tracking via `sdk.tracking.enableElement` | ||
| - Click scenarios: direct, descendant, ancestor | ||
| - Consent gating | ||
| - Identify and reset with session persistence | ||
| - Live updates: global toggle and per-entry override | ||
| - Preview panel forced-live mode | ||
| - Nested entries with recursive resolution | ||
| - Rich text rendering with inline merge tags | ||
| - Feature flag subscription with auto-emitted view events | ||
| - Analytics event display with heartbeat deduplication | ||
| - Multi-route navigation with conversion tracking | ||
|
|
||
| ## Prerequisites | ||
|
|
||
| - Node.js ^24.15.0 (to match `.nvmrc`) | ||
| - pnpm 10.x | ||
|
|
||
| ## Quick start | ||
|
|
||
| From the **repository root**: | ||
|
|
||
| ```sh | ||
| pnpm build:pkgs | ||
| pnpm implementation:run -- web-sdk_angular implementation:install | ||
| pnpm implementation:run -- web-sdk_angular serve:mocks | ||
| pnpm implementation:run -- web-sdk_angular dev | ||
| ``` | ||
|
|
||
| The app is available at `http://localhost:4200`. The mock server must be running for entry data and | ||
| variant resolution to work. | ||
|
|
||
| Other commands from the **repository root**: | ||
|
|
||
| ```sh | ||
| pnpm implementation:run -- web-sdk_angular build | ||
| pnpm implementation:run -- web-sdk_angular typecheck | ||
| ``` | ||
|
|
||
| Or equivalently from the **implementation directory**: | ||
|
|
||
| ```sh | ||
| pnpm dev | ||
| pnpm build | ||
| pnpm typecheck | ||
| ``` | ||
|
|
||
| ## Environment variables | ||
|
|
||
| Copy `.env.example` to `.env`: | ||
|
|
||
| ```sh | ||
| cp .env.example .env | ||
| ``` | ||
|
|
||
| ## Related | ||
|
|
||
| - [@contentful/optimization-web](../../packages/web/web-sdk/README.md) — Web SDK | ||
|
nalchevanidze marked this conversation as resolved.
|
||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,62 @@ | ||
| { | ||
| "$schema": "./node_modules/@angular/cli/lib/config/schema.json", | ||
| "version": 1, | ||
| "newProjectRoot": "projects", | ||
| "projects": { | ||
| "web-sdk_angular": { | ||
| "projectType": "application", | ||
| "root": "", | ||
| "sourceRoot": "src", | ||
| "prefix": "app", | ||
| "architect": { | ||
| "build": { | ||
| "builder": "@angular/build:application", | ||
| "options": { | ||
| "outputPath": "dist/web-sdk_angular", | ||
| "index": "src/index.html", | ||
| "browser": "src/main.ts", | ||
| "tsConfig": "tsconfig.json", | ||
| "assets": [], | ||
| "styles": ["src/styles.css"] | ||
| }, | ||
| "configurations": { | ||
| "production": { | ||
| "budgets": [ | ||
| { | ||
| "type": "initial", | ||
| "maximumWarning": "500kB", | ||
| "maximumError": "1MB" | ||
| } | ||
| ], | ||
| "outputHashing": "all" | ||
| }, | ||
| "development": { | ||
| "optimization": false, | ||
| "sourceMap": true | ||
| } | ||
| }, | ||
| "defaultConfiguration": "production" | ||
| }, | ||
| "serve": { | ||
| "builder": "@angular/build:dev-server", | ||
| "configurations": { | ||
| "production": { | ||
| "buildTarget": "web-sdk_angular:build:production" | ||
| }, | ||
| "development": { | ||
| "buildTarget": "web-sdk_angular:build:development" | ||
| } | ||
| }, | ||
| "defaultConfiguration": "development", | ||
| "options": { | ||
| "port": 4200 | ||
| } | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| "cli": { | ||
| "analytics": false, | ||
| "packageManager": "pnpm" | ||
| } | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| { | ||
| "name": "@implementation/web-sdk_angular", | ||
| "private": true, | ||
| "version": "0.0.0", | ||
| "description": "Reference implementation of @contentful/optimization-web for Angular applications.", | ||
| "license": "MIT", | ||
| "scripts": { | ||
| "dev": "ng serve", | ||
| "build": "ng build", | ||
| "clean": "rimraf ./dist", | ||
| "serve:mocks": "pm2 start --name web-sdk_angular-mocks \"pnpm --dir ../../lib/mocks serve\"", | ||
| "serve:mocks:stop": "pm2 stop web-sdk_angular-mocks && pm2 delete web-sdk_angular-mocks", | ||
| "test:unit": "echo \"No unit tests necessary\"", | ||
| "typecheck": "tsc -p tsconfig.json --noEmit" | ||
| }, | ||
| "dependencies": { | ||
| "@angular/common": "^22.0.0", | ||
| "@angular/compiler": "^22.0.0", | ||
| "@angular/core": "^22.0.0", | ||
|
nalchevanidze marked this conversation as resolved.
|
||
| "@angular/platform-browser": "^22.0.0", | ||
| "@angular/router": "^22.0.0", | ||
| "@contentful/optimization-web": "*", | ||
| "@contentful/optimization-web-preview-panel": "*", | ||
| "@contentful/rich-text-types": "^17.2.7", | ||
| "contentful": "^11.12.4", | ||
| "rxjs": "~7.8.0", | ||
| "tslib": "^2.8.1" | ||
| }, | ||
| "devDependencies": { | ||
| "@angular/build": "^22.0.0", | ||
| "@angular/cli": "^22.0.0", | ||
| "@angular/compiler-cli": "^22.0.0", | ||
| "@types/node": "^24.0.13", | ||
|
nalchevanidze marked this conversation as resolved.
|
||
| "pm2": "^6.0.14", | ||
| "rimraf": "^6.1.3", | ||
| "typescript": "~6.0.3" | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,8 @@ | ||
| sharedWorkspaceLockfile: false | ||
|
|
||
| overrides: | ||
| '@contentful/optimization-api-client': 'file:../../pkgs/contentful-optimization-api-client-0.0.0.tgz' | ||
| '@contentful/optimization-api-schemas': 'file:../../pkgs/contentful-optimization-api-schemas-0.0.0.tgz' | ||
| '@contentful/optimization-core': 'file:../../pkgs/contentful-optimization-core-0.0.0.tgz' | ||
| '@contentful/optimization-web': 'file:../../pkgs/contentful-optimization-web-0.0.0.tgz' | ||
| '@contentful/optimization-web-preview-panel': 'file:../../pkgs/contentful-optimization-web-preview-panel-0.0.0.tgz' |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,38 @@ | ||
| import { | ||
| type ApplicationConfig, | ||
| provideBrowserGlobalErrorListeners, | ||
| provideZonelessChangeDetection, | ||
| } from '@angular/core' | ||
| import { provideRouter } from '@angular/router' | ||
| import { routes } from './app.routes' | ||
| import { provideContentfulOptimizationConfig, resolveLogLevel } from './config' | ||
|
|
||
| export const appConfig: ApplicationConfig = { | ||
| providers: [ | ||
| provideBrowserGlobalErrorListeners(), | ||
| provideZonelessChangeDetection(), | ||
| provideRouter(routes), | ||
| provideContentfulOptimizationConfig({ | ||
| clientId: import.meta.env.PUBLIC_NINETAILED_CLIENT_ID ?? 'mock-client-id', | ||
| environment: import.meta.env.PUBLIC_NINETAILED_ENVIRONMENT ?? 'main', | ||
| insightsBaseUrl: | ||
| import.meta.env.PUBLIC_INSIGHTS_API_BASE_URL ?? 'http://localhost:8000/insights/', | ||
| experienceBaseUrl: | ||
| import.meta.env.PUBLIC_EXPERIENCE_API_BASE_URL ?? 'http://localhost:8000/experience/', | ||
| logLevel: resolveLogLevel(import.meta.env.PUBLIC_OPTIMIZATION_LOG_LEVEL), | ||
| locale: 'en-US', | ||
| app: { name: 'ContentfulOptimization SDK - Angular Web Reference', version: '0.0.0' }, | ||
| autoTrackEntryInteraction: { views: true, clicks: true, hovers: true }, | ||
| contentful: { | ||
| accessToken: import.meta.env.PUBLIC_CONTENTFUL_TOKEN ?? 'mock-token', | ||
| environment: import.meta.env.PUBLIC_CONTENTFUL_ENVIRONMENT ?? 'master', | ||
| spaceId: import.meta.env.PUBLIC_CONTENTFUL_SPACE_ID ?? 'mock-space-id', | ||
| cdaHost: import.meta.env.PUBLIC_CONTENTFUL_CDA_HOST ?? 'localhost:8000', | ||
| basePath: import.meta.env.PUBLIC_CONTENTFUL_BASE_PATH ?? 'contentful', | ||
| }, | ||
| ...(import.meta.env.PUBLIC_OPTIMIZATION_ENABLE_PREVIEW_PANEL !== 'false' | ||
| ? { previewPanel: {} } | ||
| : {}), | ||
| }), | ||
| ], | ||
| } |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,18 @@ | ||
| <nav> | ||
| <a | ||
| data-testid="link-home" | ||
| routerLink="/" | ||
| routerLinkActive="active" | ||
| [routerLinkActiveOptions]="{ exact: true }" | ||
| >Home</a | ||
| > | ||
| <a data-testid="link-page-two" routerLink="/page-two" routerLinkActive="active">Page Two</a> | ||
| </nav> | ||
| <div class="app-layout"> | ||
| <aside class="app-sidebar"> | ||
| <app-tracking-log /> | ||
| </aside> | ||
| <main> | ||
| <router-outlet /> | ||
| </main> | ||
| </div> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,9 @@ | ||
| import type { Routes } from '@angular/router' | ||
| import { Home } from './pages/home' | ||
| import { PageTwo } from './pages/page-two' | ||
|
|
||
| export const routes: Routes = [ | ||
| { path: '', component: Home }, | ||
| { path: 'page-two', component: PageTwo }, | ||
| { path: '**', redirectTo: '' }, | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,16 @@ | ||
| import { Component, inject } from '@angular/core' | ||
| import { RouterLink, RouterLinkActive, RouterOutlet } from '@angular/router' | ||
| import { TrackingLog } from './components/tracking-log' | ||
| import { NgContentfulOptimization } from './services/optimization' | ||
|
|
||
| @Component({ | ||
| selector: 'app-root', | ||
| imports: [RouterOutlet, RouterLink, RouterLinkActive, TrackingLog], | ||
| templateUrl: './app.html', | ||
| }) | ||
| export class App { | ||
| constructor() { | ||
| // forces singleton creation on startup to wire up page tracking before first route | ||
| inject(NgContentfulOptimization) | ||
| } | ||
| } |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.