@vskstudio/takt-astro 0.2.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 +21 -0
- package/README.md +70 -0
- package/Takt.astro +10 -0
- package/dist/index.d.ts +38 -0
- package/dist/index.js +61 -0
- package/package.json +68 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 VSK Studio
|
|
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.md
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
# @vskstudio/takt-astro
|
|
2
|
+
|
|
3
|
+
Astro integration for [Takt](https://github.com/vskstudio/takt-core), privacy-friendly analytics. It injects a tiny browser runtime that boots Takt, fires the initial pageview, and tracks client-side navigations — including [Astro View Transitions](https://docs.astro.build/en/guides/view-transitions/).
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
pnpm add @vskstudio/takt-astro @vskstudio/takt-core
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Usage
|
|
12
|
+
|
|
13
|
+
Pick **one** of the two paths below — not both. Both boot core's default instance, so combining them would just re-initialise.
|
|
14
|
+
|
|
15
|
+
### Integration (recommended)
|
|
16
|
+
|
|
17
|
+
```js
|
|
18
|
+
// astro.config.mjs
|
|
19
|
+
import { defineConfig } from 'astro/config'
|
|
20
|
+
import takt from '@vskstudio/takt-astro'
|
|
21
|
+
|
|
22
|
+
export default defineConfig({
|
|
23
|
+
integrations: [takt({ domain: 'example.com' })],
|
|
24
|
+
})
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### `<Takt />` component
|
|
28
|
+
|
|
29
|
+
For per-layout control, place the component in a layout `<head>`:
|
|
30
|
+
|
|
31
|
+
```astro
|
|
32
|
+
---
|
|
33
|
+
import Takt from '@vskstudio/takt-astro/Takt.astro'
|
|
34
|
+
---
|
|
35
|
+
<head>
|
|
36
|
+
<Takt domain="example.com" />
|
|
37
|
+
</head>
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## Options
|
|
41
|
+
|
|
42
|
+
Both the integration and the component accept the same options:
|
|
43
|
+
|
|
44
|
+
| Option | Type | Default | Description |
|
|
45
|
+
| --- | --- | --- | --- |
|
|
46
|
+
| `domain` | `string` | `location.hostname` | Site identifier sent with every event. |
|
|
47
|
+
| `endpoint` | `string` | `/api/event` | Ingestion endpoint. |
|
|
48
|
+
| `outbound` | `boolean` | `false` | Auto-track outbound link clicks. |
|
|
49
|
+
| `files` | `boolean` | `false` | Auto-track file downloads. |
|
|
50
|
+
| `spa` | `boolean` | `true` | Track client-side navigations. |
|
|
51
|
+
| `respectDnt` | `boolean` | `true` | Suppress events when Do Not Track is on. |
|
|
52
|
+
| `excludeLocalhost` | `boolean` | `true` | Suppress events on localhost / private IPs. |
|
|
53
|
+
|
|
54
|
+
## View Transitions
|
|
55
|
+
|
|
56
|
+
Astro's client router navigates via `history.pushState`. Core's SPA tracking patches `pushState`, so a single pageview fires per client navigation — including View Transitions DOM swaps — while `init()` fires the one initial pageview. That single source means navigations are never double-counted. The runtime is SSR/prerender safe — it only runs in the browser.
|
|
57
|
+
|
|
58
|
+
## Custom events
|
|
59
|
+
|
|
60
|
+
Re-exported from core for convenience:
|
|
61
|
+
|
|
62
|
+
```js
|
|
63
|
+
import { track } from '@vskstudio/takt-astro'
|
|
64
|
+
|
|
65
|
+
track('Signup', { revenue: { amount: '9.00', currency: 'USD' } })
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## License
|
|
69
|
+
|
|
70
|
+
MIT
|
package/Takt.astro
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
---
|
|
2
|
+
import { resolveOptions, type TaktOptions } from './src/options'
|
|
3
|
+
import { buildRuntime } from './src/runtime'
|
|
4
|
+
|
|
5
|
+
type Props = TaktOptions
|
|
6
|
+
|
|
7
|
+
const runtime = buildRuntime(resolveOptions(Astro.props))
|
|
8
|
+
---
|
|
9
|
+
<!-- Pick ONE install path — this component OR the integration — not both. -->
|
|
10
|
+
<script is:inline type="module" set:html={runtime}></script>
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { AstroIntegration } from 'astro';
|
|
2
|
+
import { InitOptions } from '@vskstudio/takt-core';
|
|
3
|
+
export { InitOptions, TrackOptions, optIn, optOut, pageview, track } from '@vskstudio/takt-core';
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Options for the Takt integration and `<Takt />` component. Mirrors core's
|
|
7
|
+
* {@link InitOptions} naming; `spa` maps to core's `auto`.
|
|
8
|
+
*/
|
|
9
|
+
interface TaktOptions {
|
|
10
|
+
/** Site identifier sent with every event. Defaults to `location.hostname`. */
|
|
11
|
+
domain?: string;
|
|
12
|
+
/** Ingestion endpoint. Defaults to `/api/event`. */
|
|
13
|
+
endpoint?: string;
|
|
14
|
+
/** Auto-track outbound link clicks. */
|
|
15
|
+
outbound?: boolean;
|
|
16
|
+
/** Auto-track file downloads. */
|
|
17
|
+
files?: boolean;
|
|
18
|
+
/** Track client-side navigations (history + Astro View Transitions). Default `true`. */
|
|
19
|
+
spa?: boolean;
|
|
20
|
+
/** Suppress events when the browser's Do Not Track is enabled. Default `true`. */
|
|
21
|
+
respectDnt?: boolean;
|
|
22
|
+
/** Suppress events on localhost and private IP ranges. Default `true`. */
|
|
23
|
+
excludeLocalhost?: boolean;
|
|
24
|
+
}
|
|
25
|
+
declare function resolveOptions(options?: TaktOptions): InitOptions;
|
|
26
|
+
|
|
27
|
+
/** Pick ONE install path — this integration OR the `<Takt />` component — not both. */
|
|
28
|
+
declare function takt(options?: TaktOptions): AstroIntegration;
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Build the browser runtime that boots Takt.
|
|
32
|
+
*
|
|
33
|
+
* Returned as a source string because Astro's `injectScript` and the `<Takt />`
|
|
34
|
+
* component both take a raw module body.
|
|
35
|
+
*/
|
|
36
|
+
declare function buildRuntime(options: InitOptions): string;
|
|
37
|
+
|
|
38
|
+
export { type TaktOptions, buildRuntime, takt as default, resolveOptions, takt };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
// src/options.ts
|
|
2
|
+
function resolveOptions(options = {}) {
|
|
3
|
+
return {
|
|
4
|
+
domain: options.domain,
|
|
5
|
+
endpoint: options.endpoint,
|
|
6
|
+
outbound: options.outbound ?? false,
|
|
7
|
+
files: options.files ?? false,
|
|
8
|
+
respectDnt: options.respectDnt ?? true,
|
|
9
|
+
excludeLocalhost: options.excludeLocalhost ?? true,
|
|
10
|
+
auto: options.spa ?? true
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// src/runtime.ts
|
|
15
|
+
function buildRuntime(options) {
|
|
16
|
+
const json = JSON.stringify(options).replace(/</g, "\\u003c").replace(/>/g, "\\u003e").replace(/&/g, "\\u0026");
|
|
17
|
+
return [
|
|
18
|
+
`import { init } from '@vskstudio/takt-core';`,
|
|
19
|
+
// SSR/prerender guard: this module is evaluated under Node when Astro
|
|
20
|
+
// prerenders, where window/init's browser APIs are absent.
|
|
21
|
+
`if (typeof window !== 'undefined' && !window.__takt) {`,
|
|
22
|
+
` const o = ${json};`,
|
|
23
|
+
// Idempotent across both entry paths (integration + <Takt/>): the flag stops
|
|
24
|
+
// a second boot from disposing the first instance's listeners.
|
|
25
|
+
` window.__takt = true;`,
|
|
26
|
+
// Single source of pageviews. init() enables core's SPA tracking, which
|
|
27
|
+
// patches history.pushState/replaceState. Astro's ClientRouter navigates via
|
|
28
|
+
// pushState and does NOT replace the history object on DOM swap, so the patch
|
|
29
|
+
// persists and fires one pageview per View Transitions navigation. init()
|
|
30
|
+
// also fires the initial pageview. We therefore do NOT listen to
|
|
31
|
+
// astro:page-load — doing so would double-count every in-app navigation.
|
|
32
|
+
` init(o);`,
|
|
33
|
+
`}`
|
|
34
|
+
].join("\n");
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
// src/integration.ts
|
|
38
|
+
function takt(options = {}) {
|
|
39
|
+
const runtime = buildRuntime(resolveOptions(options));
|
|
40
|
+
return {
|
|
41
|
+
name: "@vskstudio/takt-astro",
|
|
42
|
+
hooks: {
|
|
43
|
+
"astro:config:setup": ({ injectScript }) => {
|
|
44
|
+
injectScript("page", runtime);
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// src/index.ts
|
|
51
|
+
import { track, pageview, optOut, optIn } from "@vskstudio/takt-core";
|
|
52
|
+
export {
|
|
53
|
+
buildRuntime,
|
|
54
|
+
takt as default,
|
|
55
|
+
optIn,
|
|
56
|
+
optOut,
|
|
57
|
+
pageview,
|
|
58
|
+
resolveOptions,
|
|
59
|
+
takt,
|
|
60
|
+
track
|
|
61
|
+
};
|
package/package.json
ADDED
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vskstudio/takt-astro",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Astro integration for Takt privacy-friendly analytics",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"author": "VSK Studio",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"keywords": [
|
|
10
|
+
"analytics",
|
|
11
|
+
"privacy",
|
|
12
|
+
"astro",
|
|
13
|
+
"astro-integration",
|
|
14
|
+
"withastro",
|
|
15
|
+
"takt"
|
|
16
|
+
],
|
|
17
|
+
"homepage": "https://github.com/vskstudio/takt-astro#readme",
|
|
18
|
+
"repository": {
|
|
19
|
+
"type": "git",
|
|
20
|
+
"url": "git+https://github.com/vskstudio/takt-astro.git"
|
|
21
|
+
},
|
|
22
|
+
"bugs": {
|
|
23
|
+
"url": "https://github.com/vskstudio/takt-astro/issues"
|
|
24
|
+
},
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"exports": {
|
|
29
|
+
".": {
|
|
30
|
+
"types": "./dist/index.d.ts",
|
|
31
|
+
"import": "./dist/index.js",
|
|
32
|
+
"default": "./dist/index.js"
|
|
33
|
+
},
|
|
34
|
+
"./Takt.astro": "./Takt.astro",
|
|
35
|
+
"./package.json": "./package.json"
|
|
36
|
+
},
|
|
37
|
+
"files": [
|
|
38
|
+
"dist",
|
|
39
|
+
"Takt.astro"
|
|
40
|
+
],
|
|
41
|
+
"engines": {
|
|
42
|
+
"node": ">=18"
|
|
43
|
+
},
|
|
44
|
+
"peerDependencies": {
|
|
45
|
+
"@vskstudio/takt-core": ">=0.2.0",
|
|
46
|
+
"astro": ">=4"
|
|
47
|
+
},
|
|
48
|
+
"devDependencies": {
|
|
49
|
+
"@changesets/cli": "^2.31.0",
|
|
50
|
+
"@size-limit/preset-small-lib": "^11.1.6",
|
|
51
|
+
"@vskstudio/takt-core": "^0.2.0",
|
|
52
|
+
"astro": "^5.0.0",
|
|
53
|
+
"eslint": "^9.0.0",
|
|
54
|
+
"size-limit": "^11.1.6",
|
|
55
|
+
"tsup": "^8.3.0",
|
|
56
|
+
"typescript": "^5.6.0",
|
|
57
|
+
"typescript-eslint": "^8.0.0",
|
|
58
|
+
"vitest": "^2.1.0"
|
|
59
|
+
},
|
|
60
|
+
"scripts": {
|
|
61
|
+
"build": "tsup",
|
|
62
|
+
"typecheck": "tsc --noEmit",
|
|
63
|
+
"lint": "eslint .",
|
|
64
|
+
"test": "vitest run",
|
|
65
|
+
"size": "size-limit",
|
|
66
|
+
"release": "pnpm build && changeset publish"
|
|
67
|
+
}
|
|
68
|
+
}
|