google / google/site-kit-wp

`googlesitekit-intents` entry point and registry

Open
#13,469 0 comments 0 reactions 0 assignees View on GitHub
P1 Team S Type: Enhancement
Dominant language
JavaScript
Stars
1.4k
Forks
384
Avg merge
4d 14h
Merged PRs (30d)
77

Description

## Feature Description

The plugin's JavaScript already has a shared registry for modules. `googlesitekit-modules` is a script of its own that creates the registry, hangs it off `global.googlesitekit.modules`, and every module entry point registers into it. Intents need the same arrangement, so an intent type can ship its screen from wherever its own code already lives instead of adding it to the shared dashboard bundle.

This issue adds a `googlesitekit-intents` script that creates the intent registry and exposes it as `global.googlesitekit.intents`, and registers the Ads conversion tracking intent into it from the existing Ads module entry point. `googlesitekit-modules-ads.js` is loaded on every Site Kit admin screen whether or not the Ads module is active — that is the same mechanism that lets the Ads setup banner render for someone who has never used Ads — so the intent's component is in the registry either way, and nothing extra is needed to survive an inactive module.

The registry stores and returns components. Nothing renders from it yet: the renderer that looks a component up by intent ID is #13472.

Link to the design doc: https://docs.google.com/document/d/1-8aikH7EzELWZCFuava3izGfhUVPiOFE3Oww4czjTW0/edit?tab=t.0

---------------

_Do not alter or remove anything below. The following sections will be managed by moderators only._

## Acceptance criteria

* A `googlesitekit-intents` script is built from a new webpack entry and registered as a Site Kit asset that depends on `googlesitekit-data` and `googlesitekit-api`.
* Loading the script sets `global.googlesitekit.intents` to the intent registry, and the registry is also the module's default export.
* The registry exposes `registerIntent( slug, { Component } )` and a lookup that returns the registration for a slug, and `undefined` for a slug that was never registered.
* Registering a slug that is already registered keeps the first registration and logs a console warning naming the slug, in the same form as the notifications registry.
* The `googlesitekit-modules-ads` entry registers the `ads-conversion-tracking` intent, so it is present in `global.googlesitekit.intents` on Site Kit admin screens whether or not the Ads module is active.
* Every Site Kit screen renders the same content as before this issue.

## Implementation Brief

* [ ] In `assets/js/googlesitekit/intents/index.ts` (new file):
* Keep the registrations in a module-scope object, `Record< string, IntentRegistration >`, where `IntentRegistration` is an exported interface with a single `Component` property typed as a React component that takes the intent `payload`.
* Export `createIntents()`, which returns an object with two methods, following the shape of `createNotifications` in `assets/js/googlesitekit/notifications/index.js`:
* `registerIntent( slug: string, settings: IntentRegistration ): void` stores `settings` under `slug`. When `slug` is already registered it keeps the first registration, writes `Could not register intent with slug "${ slug }". Intent "${ slug }" is already registered.` with `global.console.warn`, and returns — the same wording the notifications registry uses.
* `getRegisteredIntent( slug: string ): IntentRegistration | undefined` returns the stored registration, or `undefined` when nothing is registered for that slug.

* [ ] In `assets/js/googlesitekit-intents.ts` (new file):
* Import `createIntents` from `./googlesitekit/intents`, create the registry, set `global.googlesitekit = global.googlesitekit || {}` and then `global.googlesitekit.intents`, and export the registry as the default export. Follow `assets/js/googlesitekit-modules.ts`.

* [ ] In `assets/webpack/modules.config.js`:
* Add `'googlesitekit-intents': './js/googlesitekit-intents.ts'` to the `entry` map, next to `'googlesitekit-modules'`.

* [ ] In `webpack/common.js`:
* Add `'googlesitekit-intents': [ 'googlesitekit', 'intents' ]` to `siteKitExternals`, so `import Intents from 'googlesitekit-intents'` in another bundle resolves to `global.googlesitekit.intents`.

* [ ] In `includes/Core/Assets/Assets.php`:
* Register a new `Script` with the handle `googlesitekit-intents`, `'src' => $base_url . 'js/googlesitekit-intents.js'` and `'dependencies' => array( 'googlesitekit-api', 'googlesitekit-data' )`, next to the `googlesitekit-modules` registration.
* Add `'googlesitekit-intents'` to the shared list in `get_asset_dependencies()`, next to `'googlesitekit-notifications'`, so it is enqueued and printed before the screen bundles that read the global.

* [ ] In `includes/Modules/Ads.php`:
* Add `'googlesitekit-intents'` to the `dependencies` array of the `googlesitekit-modules-ads` `Script` in `setup_assets()`.

* [ ] In `assets/js/modules/ads/constants.js`:
* Add `export const ADS_CONVERSION_TRACKING_INTENT_SLUG = 'ads-conversion-tracking';`.

* [ ] In `assets/js/modules/ads/components/intents/AdsConversionTrackingIntent.tsx` (new file):
* Add the component the intent registers. In this issue it returns `null`; #13473 builds the card in this file.

* [ ] In `assets/js/modules/ads/intents/index.ts` (new file):
* Export `registerIntents( intents )`, which calls `intents.registerIntent( ADS_CONVERSION_TRACKING_INTENT_SLUG, { Component: AdsConversionTrackingIntent } )`. Follow `assets/js/modules/ads/notifications/index.js`.

* [ ] In `assets/js/modules/ads/index.js`:
* Add `export { registerIntents } from './intents';` next to the existing `registerNotifications` export.

* [ ] In `assets/js/googlesitekit-modules-ads.ts`:
* Import `Intents from 'googlesitekit-intents'` and `registerIntents` from `./modules/ads`, and call `registerIntents( Intents )` next to `registerNotifications( Notifications )`.

### Test Coverage

* Add `assets/js/googlesitekit/intents/index.test.ts` covering:
* a registered slug is returned by `getRegisteredIntent` with the `Component` it was registered with;
* `getRegisteredIntent` returns `undefined` for a slug that was never registered;
* registering the same slug twice keeps the first registration and writes the console warning naming the slug.

## QA Brief

*

## Changelog entry

*

Contributor guide

Open the contributing guide

Research direction

Start with assets/js/googlesitekit-modules.ts, assets/js/googlesitekit/notifications/index.js, and the listed webpack and asset-registration files to trace the existing registry pattern. Run assets/js/googlesitekit/intents/index.test.ts and the relevant Ads tests while checking the googlesitekit-modules-ads entry point. Done means the intents global and asset are available, Ads registers ads-conversion-tracking even when inactive, duplicate slugs warn and preserve the first registration, and existing screens are unchanged.

Written by the indexing model from the issue text.

Assessment

Tech stack
javascript, php, react, typescript, webpack
Domain
backend, build-system, frontend
Issue type
Feature
Difficulty
4/5
Estimated time
3-5 days
Activity status
Active
Clarity
Clearly specified
Newbie friendliness
72/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.