@whichly/astro 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/README.md ADDED
@@ -0,0 +1,98 @@
1
+ # @whichly/astro
2
+
3
+ Astro integration and components for Whichly variant previews.
4
+
5
+ Use Whichly in Astro marketing pages to preview alternate versions of the same page or section. Variants may contain plain Astro markup, Astro components, or hydrated islands such as React components.
6
+
7
+ ## Install
8
+
9
+ ```sh
10
+ npm i @whichly/astro
11
+ # or
12
+ pnpm add @whichly/astro
13
+ ```
14
+
15
+ ## Configure
16
+
17
+ ```js
18
+ // astro.config.mjs
19
+ import { defineConfig } from "astro/config";
20
+ import whichly from "@whichly/astro";
21
+
22
+ export default defineConfig({
23
+ integrations: [whichly()],
24
+ });
25
+ ```
26
+
27
+ The integration accepts optional runtime settings:
28
+
29
+ ```js
30
+ whichly({
31
+ floating: true,
32
+ param: "vp",
33
+ });
34
+ ```
35
+
36
+ `WhichlyBlock.astro` also boots the runtime once per page when a block is present, so the picker works even if an Astro setup does not include the injected integration script in development.
37
+
38
+ ## Use
39
+
40
+ ```astro
41
+ ---
42
+ import WhichlyBlock from "@whichly/astro/components/WhichlyBlock.astro";
43
+ import WhichlyVariant from "@whichly/astro/components/WhichlyVariant.astro";
44
+ import ReactHero from "../components/ReactHero.tsx";
45
+ import AstroHero from "../components/AstroHero.astro";
46
+ ---
47
+
48
+ <WhichlyBlock name="hero">
49
+ <WhichlyVariant name="astro">
50
+ <AstroHero />
51
+ </WhichlyVariant>
52
+
53
+ <WhichlyVariant name="react">
54
+ <ReactHero client:load />
55
+ </WhichlyVariant>
56
+ </WhichlyBlock>
57
+ ```
58
+
59
+ The first variant is shown by default. Selecting another variant updates the URL, for example:
60
+
61
+ ```txt
62
+ ?vp=hero:react
63
+ ```
64
+
65
+ This makes preview links shareable.
66
+
67
+ ## Important layout rule
68
+
69
+ Place `WhichlyBlock` / `WhichlyVariant` inside the document body. Do not wrap a component that emits a full `<html>` document or an Astro layout component that owns `<html>` / `<body>`.
70
+
71
+ Good:
72
+
73
+ ```astro
74
+ <BaseLayout>
75
+ <WhichlyBlock name="homepage">
76
+ <WhichlyVariant name="current">
77
+ <HomePageContent />
78
+ </WhichlyVariant>
79
+ <WhichlyVariant name="test">
80
+ <h1>Hello world</h1>
81
+ </WhichlyVariant>
82
+ </WhichlyBlock>
83
+ </BaseLayout>
84
+ ```
85
+
86
+ Avoid:
87
+
88
+ ```astro
89
+ <WhichlyBlock name="homepage">
90
+ <WhichlyVariant name="current">
91
+ <FullPageWithHtmlAndBody />
92
+ </WhichlyVariant>
93
+ </WhichlyBlock>
94
+ ```
95
+
96
+ ## Astro islands
97
+
98
+ Astro islands inside inactive variants may still hydrate depending on their `client:*` directive. This is intentional for the initial render-all implementation and matches the React package model.
@@ -0,0 +1,31 @@
1
+ ---
2
+ export interface Props {
3
+ name: string;
4
+ }
5
+
6
+ const { name } = Astro.props;
7
+ ---
8
+
9
+ <style is:global>
10
+ [data-whichly-block] > [data-whichly-variant] {
11
+ display: none;
12
+ }
13
+
14
+ [data-whichly-block] > [data-whichly-variant]:first-of-type {
15
+ display: contents;
16
+ }
17
+ </style>
18
+
19
+ <script>
20
+ import { createWhichlyRuntime } from "@whichly/astro/runtime";
21
+
22
+ const win = window as Window & {
23
+ __whichlyRuntime?: ReturnType<typeof createWhichlyRuntime>;
24
+ };
25
+
26
+ win.__whichlyRuntime ??= createWhichlyRuntime();
27
+ </script>
28
+
29
+ <div data-whichly-block={name}>
30
+ <slot />
31
+ </div>
@@ -0,0 +1,11 @@
1
+ ---
2
+ export interface Props {
3
+ name: string;
4
+ }
5
+
6
+ const { name } = Astro.props;
7
+ ---
8
+
9
+ <div data-whichly-variant={name}>
10
+ <slot />
11
+ </div>
package/dist/index.js ADDED
@@ -0,0 +1,23 @@
1
+ import { default as default2 } from "../components/WhichlyBlock.astro";
2
+ import { default as default3 } from "../components/WhichlyVariant.astro";
3
+ function whichly(options = {}) {
4
+ return {
5
+ name: "@whichly/astro",
6
+ hooks: {
7
+ "astro:config:setup": ({ injectScript }) => {
8
+ const runtimeOptions = JSON.stringify(options).replaceAll("<", "\\u003c");
9
+ injectScript(
10
+ "page",
11
+ `import { createWhichlyRuntime } from "@whichly/astro/runtime";
12
+ createWhichlyRuntime(${runtimeOptions});`
13
+ );
14
+ }
15
+ }
16
+ };
17
+ }
18
+ export {
19
+ default2 as WhichlyBlock,
20
+ default3 as WhichlyVariant,
21
+ whichly as default
22
+ };
23
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import type { AstroIntegration } from \"astro\";\n\nexport { default as WhichlyBlock } from \"../components/WhichlyBlock.astro\";\nexport { default as WhichlyVariant } from \"../components/WhichlyVariant.astro\";\n\nexport interface WhichlyAstroOptions {\n /**\n * Render the built-in floating picker.\n * @default true\n */\n floating?: boolean;\n /**\n * URL search param used to store selections.\n * @default \"vp\"\n */\n param?: string;\n}\n\nexport default function whichly(options: WhichlyAstroOptions = {}): AstroIntegration {\n return {\n name: \"@whichly/astro\",\n hooks: {\n \"astro:config:setup\": ({ injectScript }) => {\n const runtimeOptions = JSON.stringify(options).replaceAll(\"<\", \"\\\\u003c\");\n injectScript(\n \"page\",\n `import { createWhichlyRuntime } from \"@whichly/astro/runtime\";\\ncreateWhichlyRuntime(${runtimeOptions});`,\n );\n },\n },\n };\n}\n"],"names":[],"mappings":";;AAkBA,SAAwB,QAAQ,UAA+B,IAAsB;AACnF,SAAO;AAAA,IACL,MAAM;AAAA,IACN,OAAO;AAAA,MACL,sBAAsB,CAAC,EAAE,mBAAmB;AAC1C,cAAM,iBAAiB,KAAK,UAAU,OAAO,EAAE,WAAW,KAAK,SAAS;AACxE;AAAA,UACE;AAAA,UACA;AAAA,uBAAwF,cAAc;AAAA,QAAA;AAAA,MAE1G;AAAA,IAAA;AAAA,EACF;AAEJ;"}
@@ -0,0 +1,5 @@
1
+ import { createWhichlyRuntime } from "@whichly/core";
2
+ export {
3
+ createWhichlyRuntime
4
+ };
5
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -0,0 +1,16 @@
1
+ import { AstroIntegration } from 'astro';
2
+ export { default as WhichlyBlock } from '../components/WhichlyBlock.astro';
3
+ export { default as WhichlyVariant } from '../components/WhichlyVariant.astro';
4
+ export interface WhichlyAstroOptions {
5
+ /**
6
+ * Render the built-in floating picker.
7
+ * @default true
8
+ */
9
+ floating?: boolean;
10
+ /**
11
+ * URL search param used to store selections.
12
+ * @default "vp"
13
+ */
14
+ param?: string;
15
+ }
16
+ export default function whichly(options?: WhichlyAstroOptions): AstroIntegration;
@@ -0,0 +1,2 @@
1
+ export { createWhichlyRuntime } from '@whichly/core';
2
+ export type { WhichlyRuntime, WhichlyRuntimeOptions } from '@whichly/core';
@@ -0,0 +1,2 @@
1
+ declare const _default: import('vite').UserConfig;
2
+ export default _default;
package/package.json ADDED
@@ -0,0 +1,57 @@
1
+ {
2
+ "name": "@whichly/astro",
3
+ "version": "0.1.0",
4
+ "description": "Astro integration and components for Whichly variant previews.",
5
+ "license": "MIT",
6
+ "author": "kapishdima <kapishdima@gmail.com>",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/kapishdima/whichly.git",
10
+ "directory": "packages/astro"
11
+ },
12
+ "homepage": "https://github.com/kapishdima/whichly/tree/main/packages/astro#readme",
13
+ "bugs": {
14
+ "url": "https://github.com/kapishdima/whichly/issues"
15
+ },
16
+ "keywords": ["whichly", "astro", "variants", "ab-test", "staging", "client-review"],
17
+ "type": "module",
18
+ "main": "./dist/index.js",
19
+ "module": "./dist/index.js",
20
+ "types": "./dist/index.d.ts",
21
+ "files": ["components", "dist"],
22
+ "exports": {
23
+ ".": {
24
+ "types": "./dist/index.d.ts",
25
+ "import": "./dist/index.js"
26
+ },
27
+ "./runtime": {
28
+ "types": "./dist/runtime.d.ts",
29
+ "import": "./dist/runtime.js"
30
+ },
31
+ "./components/WhichlyBlock.astro": "./components/WhichlyBlock.astro",
32
+ "./components/WhichlyVariant.astro": "./components/WhichlyVariant.astro"
33
+ },
34
+ "publishConfig": {
35
+ "access": "public"
36
+ },
37
+ "sideEffects": true,
38
+ "scripts": {
39
+ "dev": "vite build --watch",
40
+ "build": "vite build",
41
+ "typecheck": "tsc --noEmit",
42
+ "lint": "biome check .",
43
+ "prepublishOnly": "pnpm build"
44
+ },
45
+ "dependencies": {
46
+ "@whichly/core": "workspace:*"
47
+ },
48
+ "peerDependencies": {
49
+ "astro": "^4.0.0 || ^5.0.0"
50
+ },
51
+ "devDependencies": {
52
+ "astro": "^5.0.0",
53
+ "typescript": "^5.6.3",
54
+ "vite": "^6.0.0",
55
+ "vite-plugin-dts": "^4.4.0"
56
+ }
57
+ }