@ampless/plugin-analytics-ga4 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 ampless contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.ja.md ADDED
@@ -0,0 +1,71 @@
1
+ > English: [README.md](./README.md)
2
+ >
3
+
4
+ # @ampless/plugin-analytics-ga4
5
+
6
+ [ampless](https://github.com/heavymoons/ampless) 向け Google Analytics 4 プラグイン。
7
+
8
+ > **プレリリース / アルファ版。** v1.0 まではマイナーバージョンでも破壊的変更が入る可能性があります。
9
+
10
+ descriptor ベースのプラグイン head 注入 API ([docs/tmp/plugin-extension-spec.md](https://github.com/heavymoons/ampless/blob/main/docs/tmp/plugin-extension-spec.md)、Phase 1) を使って、公開ページの `<head>` に GA4 標準の 2 つのスニペットを挿入します。
11
+
12
+ 1. 非同期 `gtag.js` ローダー (`https://www.googletagmanager.com/gtag/js?id=...`)
13
+ 2. インライン `gtag('config', '<measurementId>')` のブートストラップ
14
+
15
+ 公開 Next.js プロセス内で描画時に動くだけなので、AWS のデータ権限は不要です。`trust_level` は `untrusted`。
16
+
17
+ ## インストール
18
+
19
+ ```bash
20
+ npm install @ampless/plugin-analytics-ga4@alpha
21
+ ```
22
+
23
+ ## 設定
24
+
25
+ `cms.config.ts` に記述します:
26
+
27
+ ```ts
28
+ import { defineConfig } from 'ampless'
29
+ import analyticsGa4Plugin from '@ampless/plugin-analytics-ga4'
30
+
31
+ export default defineConfig({
32
+ // ...
33
+ plugins: [
34
+ analyticsGa4Plugin({ measurementId: 'G-XXXXXXXX' }),
35
+ ],
36
+ })
37
+ ```
38
+
39
+ | オプション | デフォルト | 備考 |
40
+ |---|---|---|
41
+ | `measurementId` | 必須 | GA4 の計測 ID。例: `G-XXXXXXXX`。空文字 `''` を渡すとプラグインを残したまま注入だけ無効化できる。 |
42
+ | `instanceId` | `'analytics-ga4'` | 生成される `<script>` 要素 id の namespace。同じサイトに複数の GA4 プロパティを入れる場合に分ける。 |
43
+
44
+ ## measurement ID の取得
45
+
46
+ 1. [Google Analytics](https://analytics.google.com/) にサインインし、対象プロパティを選択。
47
+ 2. **管理 → データストリーム → ウェブ** を開き、このサイト用ストリームを選択。
48
+ 3. 画面に `測定 ID`(`G-XXXXXXXX` の形式)が表示されるので、それを上の `measurementId` に設定。
49
+
50
+ `G-XXXXXXXX` はプロパティ識別子であって書き込み認証には使われないため、ソースコードにコミットして問題ありません。
51
+
52
+ ## 複数インスタンス
53
+
54
+ Phase 1 では複数インスタンス対応の型定義のみ追加しており、ランタイム検証は Phase 3 で正式化します ([docs/tmp/plugin-extension-roadmap.md](https://github.com/heavymoons/ampless/blob/main/docs/tmp/plugin-extension-roadmap.md))。型としては今でも次のように書けます:
55
+
56
+ ```ts
57
+ plugins: [
58
+ analyticsGa4Plugin({ instanceId: 'marketing', measurementId: 'G-AAA' }),
59
+ analyticsGa4Plugin({ instanceId: 'product', measurementId: 'G-BBB' }),
60
+ ]
61
+ ```
62
+
63
+ ## トラストレベル
64
+
65
+ `untrusted`。プラグインは `@ampless/runtime` が検証・描画する head descriptor を返すだけです。DynamoDB、S3、Lambda プロセッサーには一切触れません。
66
+
67
+ ## まだやらないこと
68
+
69
+ - **CSP nonce 連携** — Phase 1 ではインライン script に `nonce` を付与しません。ampless サイトに CSP enforcement を入れる段で別途 RFP として middleware → SSR → descriptor の通り道を設計します。
70
+ - **管理画面からの設定** — Phase 1 では `cms.config.ts` 直書きのみ。admin 管理は Phase 2。
71
+ - **ページ単位のイベント送信** — カスタムイベントはページコード側で `window.gtag('event', ...)` を呼んでください。
package/README.md ADDED
@@ -0,0 +1,71 @@
1
+ > 日本語版: [README.ja.md](./README.ja.md)
2
+ >
3
+
4
+ # @ampless/plugin-analytics-ga4
5
+
6
+ Google Analytics 4 plugin for [ampless](https://github.com/heavymoons/ampless).
7
+
8
+ > **Pre-release / alpha.** Breaking changes possible in any minor version until v1.0.
9
+
10
+ Drops the two standard GA4 snippets into every public page's `<head>` through the descriptor-based plugin head injection API ([docs/tmp/plugin-extension-spec.md](https://github.com/heavymoons/ampless/blob/main/docs/tmp/plugin-extension-spec.md), Phase 1):
11
+
12
+ 1. The async `gtag.js` loader (`https://www.googletagmanager.com/gtag/js?id=...`).
13
+ 2. An inline `gtag('config', '<measurementId>')` bootstrap.
14
+
15
+ No AWS data permissions are required — everything runs at request time inside the public Next.js process. The plugin's `trust_level` is `untrusted`.
16
+
17
+ ## Install
18
+
19
+ ```bash
20
+ npm install @ampless/plugin-analytics-ga4@alpha
21
+ ```
22
+
23
+ ## Configure
24
+
25
+ In `cms.config.ts`:
26
+
27
+ ```ts
28
+ import { defineConfig } from 'ampless'
29
+ import analyticsGa4Plugin from '@ampless/plugin-analytics-ga4'
30
+
31
+ export default defineConfig({
32
+ // ...
33
+ plugins: [
34
+ analyticsGa4Plugin({ measurementId: 'G-XXXXXXXX' }),
35
+ ],
36
+ })
37
+ ```
38
+
39
+ | Option | Default | Notes |
40
+ |---|---|---|
41
+ | `measurementId` | required | Your GA4 measurement ID, e.g. `G-XXXXXXXX`. Set to `''` to disable the plugin without removing it from `cms.config.ts`. |
42
+ | `instanceId` | `'analytics-ga4'` | Namespace used for the script element ids. Set distinct values when registering multiple GA4 properties on the same site. |
43
+
44
+ ## Getting your measurement ID
45
+
46
+ 1. Sign in to [Google Analytics](https://analytics.google.com/) and pick the property you want to install on the site.
47
+ 2. Open **Admin → Data streams → Web** and select the stream for this site.
48
+ 3. The page shows a `Measurement ID` of the form `G-XXXXXXXX`. Copy that value into the `measurementId` option above.
49
+
50
+ `G-XXXXXXXX` is safe to commit to source control — it identifies the property but does not authenticate writes.
51
+
52
+ ## Multiple instances
53
+
54
+ Phase 1 ships the type definitions for multi-instance plugins, but full runtime validation lands in Phase 3 ([docs/tmp/plugin-extension-roadmap.md](https://github.com/heavymoons/ampless/blob/main/docs/tmp/plugin-extension-roadmap.md)). The shape today:
55
+
56
+ ```ts
57
+ plugins: [
58
+ analyticsGa4Plugin({ instanceId: 'marketing', measurementId: 'G-AAA' }),
59
+ analyticsGa4Plugin({ instanceId: 'product', measurementId: 'G-BBB' }),
60
+ ]
61
+ ```
62
+
63
+ ## Trust level
64
+
65
+ `untrusted`. The plugin only contributes head descriptors that are validated and rendered by `@ampless/runtime`. It does not touch DynamoDB, S3, or any Lambda processor.
66
+
67
+ ## What it does not do (yet)
68
+
69
+ - **CSP nonce propagation** — Phase 1 emits the inline script without a `nonce`. ampless sites do not enforce a CSP today; once that lands, a dedicated RFP will wire `nonce` end-to-end (middleware → SSR → descriptor).
70
+ - **Admin UI settings** — Phase 1 reads the measurement ID from `cms.config.ts` only. Admin-managed settings come in Phase 2.
71
+ - **Per-route event tagging** — Send any custom events from your own page code (`window.gtag('event', ...)`).
@@ -0,0 +1,28 @@
1
+ import { AmplessPlugin } from 'ampless';
2
+
3
+ interface AnalyticsGa4Options {
4
+ /**
5
+ * Google Analytics 4 measurement ID, e.g. `"G-XXXXXXXX"`. An empty
6
+ * string disables the plugin (descriptors return `[]`), which is
7
+ * the recommended way to keep the dependency wired up while
8
+ * temporarily turning analytics off — for example in staging or
9
+ * before consent is granted.
10
+ */
11
+ measurementId: string;
12
+ /**
13
+ * Optional namespace for this instance. Defaults to
14
+ * `'analytics-ga4'`. Set distinct values when registering the
15
+ * plugin twice (e.g. a marketing + a product property on the same
16
+ * site).
17
+ */
18
+ instanceId?: string;
19
+ }
20
+ /**
21
+ * Factory for the GA4 plugin. Returns a plugin manifest that emits
22
+ * the two GA4 snippets via `publicHead`. The plugin is `untrusted` —
23
+ * it does not need any AWS data permissions because everything
24
+ * happens inside the public Next.js process at render time.
25
+ */
26
+ declare function analyticsGa4Plugin(options: AnalyticsGa4Options): AmplessPlugin;
27
+
28
+ export { type AnalyticsGa4Options, analyticsGa4Plugin as default };
package/dist/index.js ADDED
@@ -0,0 +1,44 @@
1
+ // src/index.ts
2
+ import { definePlugin } from "ampless";
3
+ function analyticsGa4Plugin(options) {
4
+ const { measurementId, instanceId = "analytics-ga4" } = options;
5
+ return definePlugin({
6
+ name: "analytics-ga4",
7
+ instanceId,
8
+ displayName: { en: "Google Analytics 4", ja: "Google Analytics 4" },
9
+ apiVersion: 1,
10
+ trust_level: "untrusted",
11
+ capabilities: ["publicHead"],
12
+ publicHead() {
13
+ if (!measurementId) return [];
14
+ return [
15
+ {
16
+ type: "script",
17
+ id: `ga4-loader-${instanceId}`,
18
+ src: `https://www.googletagmanager.com/gtag/js?id=${encodeURIComponent(
19
+ measurementId
20
+ )}`,
21
+ strategy: "afterInteractive"
22
+ },
23
+ {
24
+ type: "inlineScript",
25
+ id: `ga4-init-${instanceId}`,
26
+ strategy: "afterInteractive",
27
+ // Standard GA4 bootstrap. We JSON.stringify the measurement
28
+ // ID so any future surprises (special characters in
29
+ // measurement IDs, accidental quote injection) stay
30
+ // contained.
31
+ body: [
32
+ "window.dataLayer = window.dataLayer || [];",
33
+ "function gtag(){dataLayer.push(arguments);}",
34
+ "gtag('js', new Date());",
35
+ `gtag('config', ${JSON.stringify(measurementId)});`
36
+ ].join("\n")
37
+ }
38
+ ];
39
+ }
40
+ });
41
+ }
42
+ export {
43
+ analyticsGa4Plugin as default
44
+ };
package/package.json ADDED
@@ -0,0 +1,43 @@
1
+ {
2
+ "name": "@ampless/plugin-analytics-ga4",
3
+ "version": "0.1.0",
4
+ "description": "Google Analytics 4 plugin for ampless",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "exports": {
8
+ ".": {
9
+ "import": "./dist/index.js",
10
+ "types": "./dist/index.d.ts"
11
+ }
12
+ },
13
+ "files": [
14
+ "dist",
15
+ "README.md"
16
+ ],
17
+ "publishConfig": {
18
+ "access": "public"
19
+ },
20
+ "repository": {
21
+ "type": "git",
22
+ "url": "https://github.com/heavymoons/ampless.git",
23
+ "directory": "packages/plugin-analytics-ga4"
24
+ },
25
+ "homepage": "https://github.com/heavymoons/ampless/tree/main/packages/plugin-analytics-ga4#readme",
26
+ "bugs": "https://github.com/heavymoons/ampless/issues",
27
+ "dependencies": {
28
+ "ampless": "1.0.0-alpha.16"
29
+ },
30
+ "keywords": [
31
+ "ampless",
32
+ "plugin",
33
+ "analytics",
34
+ "ga4",
35
+ "google-analytics"
36
+ ],
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "dev": "tsup --watch",
40
+ "lint": "tsc --noEmit",
41
+ "test": "vitest run --passWithNoTests"
42
+ }
43
+ }