astro-indexnow 0.0.5 → 1.0.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) 2025 Velohost Technologies
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 CHANGED
@@ -1,35 +1,37 @@
1
1
  # astro-indexnow
2
2
 
3
- An Astro integration that automatically submits **changed pages** to **IndexNow**
3
+ An Astro integration that automatically submits **all built pages** to **IndexNow**
4
4
  after each build, helping search engines discover updates faster.
5
5
 
6
6
  Designed to follow Astro’s official integration patterns (like `@astrojs/sitemap`):
7
+
7
8
  - No interactive prompts
8
- - No secret injection
9
- - Explicit, config-driven usage
10
- - CI-safe and deterministic
9
+ - No automatic file mutation
10
+ - Explicit, configdriven usage
11
+ - CIsafe and deterministic
12
+ - Zero runtime impact
11
13
 
12
14
  ---
13
15
 
14
16
  ## What is IndexNow?
15
17
 
16
18
  [IndexNow](https://www.indexnow.org/) is a protocol supported by search engines
17
- like **Bing** and **Yandex** that allows websites to proactively notify them
18
- when URLs are added, updated, or deleted.
19
+ such as **Bing** and **Yandex** that allows websites to proactively notify them
20
+ when URLs are added or updated.
19
21
 
20
- Instead of waiting for crawlers, your site tells search engines exactly
21
- what changed.
22
+ Instead of waiting for crawlers, your site directly tells search engines
23
+ which URLs should be re‑crawled.
22
24
 
23
25
  ---
24
26
 
25
27
  ## Features
26
28
 
27
29
  - 🚀 Submits URLs to IndexNow **at build time**
28
- - 🔁 Only submits **changed pages** (no unnecessary resubmits)
29
- - 🔒 No secrets stored or prompted — fully explicit config
30
+ - 🔁 Submits **all generated pages** every build (simple & reliable)
31
+ - 🔒 No secrets prompted or stored automatically
30
32
  - 🧠 Uses Astro’s `site` config as the canonical base URL
31
33
  - 🧪 Safe for CI/CD pipelines
32
- - 🧩 Zero runtime impact
34
+ - 🧩 No client‑side or runtime code added
33
35
 
34
36
  ---
35
37
 
@@ -39,48 +41,89 @@ what changed.
39
41
  npm install astro-indexnow
40
42
  ```
41
43
 
42
- or using Astro’s helper:
44
+ Or using Astro’s helper:
43
45
 
44
46
  ```bash
45
47
  npx astro add astro-indexnow
46
48
  ```
47
49
 
48
- > Note: Like other Astro integrations, `astro add` installs the integration
49
- > but does not inject configuration values. See usage below.
50
+ > **Note**
51
+ > Like other Astro integrations, `astro add` installs the package but does **not**
52
+ > inject configuration values. You must configure it manually (see below).
53
+
54
+ ---
55
+
56
+ ## Step 1 — Get your IndexNow key
57
+
58
+ Generate an IndexNow API key here:
59
+
60
+ 👉 https://www.bing.com/indexnow/getstarted
61
+
62
+ You will receive:
63
+ - an **API key** (a long string)
64
+ - instructions to create a **key file**
50
65
 
51
66
  ---
52
67
 
53
- ## Usage
68
+ ## Step 2 — Create the key file (required)
69
+
70
+ IndexNow requires proof that you own the site.
54
71
 
55
- `astro-indexnow` follows the **same configuration pattern as `@astrojs/sitemap`**.
72
+ Create a text file named **`<YOUR_KEY>.txt`** in your Astro `public/` directory.
56
73
 
57
- ### 1) Configure your site URL
74
+ ### Example
58
75
 
59
- IndexNow requires a fully qualified, canonical site URL.
76
+ If your key is:
77
+
78
+ ```
79
+ abcd1234
80
+ ```
81
+
82
+ Create this file:
83
+
84
+ ```
85
+ public/abcd1234.txt
86
+ ```
87
+
88
+ With **exactly this content**:
89
+
90
+ ```
91
+ abcd1234
92
+ ```
60
93
 
61
- In `astro.config.mjs`:
94
+ Astro will automatically copy this file to the build output.
95
+
96
+ > ⚠️ The plugin does **not** create this file for you.
97
+
98
+ ---
99
+
100
+ ## Step 3 — Configure Astro
101
+
102
+ Add **both** your site URL and the IndexNow integration
103
+ to `astro.config.mjs`.
104
+
105
+ ### Example
62
106
 
63
107
  ```js
108
+ // @ts-check
64
109
  import { defineConfig } from "astro/config";
65
- import indexNow from "astro-indexnow";
110
+ import indexnow from "astro-indexnow";
66
111
 
67
112
  export default defineConfig({
68
113
  site: "https://example.com",
69
114
 
70
115
  integrations: [
71
- indexNow({
72
- key: "YOUR_INDEXNOW_API_KEY",
116
+ indexnow({
117
+ key: "YOUR_INDEXNOW_KEY",
73
118
  }),
74
119
  ],
75
120
  });
76
121
  ```
77
122
 
78
- ---
79
-
80
- ### 2) Using environment variables (recommended)
123
+ ### Using environment variables (recommended)
81
124
 
82
125
  ```js
83
- indexNow({
126
+ indexnow({
84
127
  key: process.env.INDEXNOW_KEY,
85
128
  });
86
129
  ```
@@ -97,16 +140,13 @@ Type: `string`
97
140
 
98
141
  Your IndexNow API key.
99
142
 
100
- You can generate a key at:
101
- - https://www.indexnow.org/
102
-
103
143
  ---
104
144
 
105
- ### `site` (required, from Astro config)
145
+ ### `site` (required)
106
146
 
107
147
  Type: `string`
108
148
 
109
- The integration reads the site’s canonical URL from:
149
+ Set via Astro’s config:
110
150
 
111
151
  ```js
112
152
  defineConfig({
@@ -114,27 +154,42 @@ defineConfig({
114
154
  })
115
155
  ```
116
156
 
117
- This **must** start with `http://` or `https://`.
157
+ Must begin with `http://` or `https://`.
158
+
159
+ ---
160
+
161
+ ### `enabled` (optional)
162
+
163
+ Type: `boolean`
164
+ Default: `true`
165
+
166
+ Disable IndexNow submissions without removing config:
167
+
168
+ ```js
169
+ indexnow({
170
+ key: "...",
171
+ enabled: false,
172
+ });
173
+ ```
118
174
 
119
175
  ---
120
176
 
121
177
  ## How It Works
122
178
 
123
- At build time, the integration:
179
+ On every `astro build`, the integration:
124
180
 
125
- 1. Reads Astro’s output directory
126
- 2. Collects all generated page URLs
127
- 3. Hashes and compares them to the previous build
128
- 4. Submits **only changed URLs** to IndexNow
129
- 5. Saves state for the next build
181
+ 1. Reads Astro’s build output directory
182
+ 2. Detects all generated pages
183
+ 3. Converts them to public URLs
184
+ 4. Submits them to IndexNow via a single POST request
130
185
 
131
- No runtime code is added to your site.
186
+ No state is stored and no runtime code is added to your site.
132
187
 
133
188
  ---
134
189
 
135
190
  ## CI / Deployment
136
191
 
137
- This integration is designed to work cleanly in CI environments.
192
+ Designed to work cleanly in CI environments.
138
193
 
139
194
  Example:
140
195
 
@@ -148,27 +203,27 @@ No prompts. No interactivity. Fully deterministic.
148
203
 
149
204
  ## Limitations
150
205
 
151
- - IndexNow submissions only run on `astro build`
152
- - Requires `site` to be configured
153
- - Requires a valid IndexNow key
154
- - Uninstalling the package does not automatically remove config
206
+ - Submissions only run on `astro build`
207
+ - Requires a valid `site` configuration
208
+ - Requires the IndexNow key file to exist
209
+ - Uninstalling the package does not remove config automatically
155
210
  (same behaviour as other Astro integrations)
156
211
 
157
212
  ---
158
213
 
159
- ## Inspiration & Philosophy
214
+ ## Philosophy
160
215
 
161
216
  This integration intentionally mirrors the behaviour of
162
217
  official Astro integrations such as:
163
218
 
164
219
  - `@astrojs/sitemap`
165
220
 
166
- Astro integrations are designed to:
167
- - avoid mutating user config implicitly
168
- - avoid prompting for secrets
169
- - rely on explicit configuration
221
+ It avoids:
222
+ - automatic config mutation
223
+ - secret prompting
224
+ - hidden side effects
170
225
 
171
- `astro-indexnow` follows these principles strictly.
226
+ Everything is explicit and predictable.
172
227
 
173
228
  ---
174
229
 
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAK9C,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,OAAO,GAAE,eAAoB,GAC5B,gBAAgB,CA0GlB"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,OAAO,CAAC;AAK9C,MAAM,WAAW,eAAe;IAC9B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,MAAM,CAAC,OAAO,UAAU,QAAQ,CAC9B,OAAO,GAAE,eAAoB,GAC5B,gBAAgB,CAkHlB"}
package/dist/index.js CHANGED
@@ -11,16 +11,16 @@ export default function indexNow(options = {}) {
11
11
  options.siteUrl ??
12
12
  (config.site ? config.site.replace(/\/$/, "") : null);
13
13
  },
14
- "astro:build:done": async ({ dir }) => {
14
+ "astro:build:done": async ({ dir, logger }) => {
15
15
  if (options.enabled === false) {
16
- console.log("[astro-indexnow] disabled");
16
+ logger.info("[astro-indexnow] disabled");
17
17
  return;
18
18
  }
19
19
  if (!options.key) {
20
20
  throw new Error("[astro-indexnow] Missing IndexNow key. Provide it in astro.config.mjs.");
21
21
  }
22
22
  if (!site) {
23
- throw new Error("[astro-indexnow] Missing `site` in astro.config.mjs (or siteUrl option).");
23
+ throw new Error("[astro-indexnow] Missing site URL. Set `site` in astro.config.mjs or pass `siteUrl`.");
24
24
  }
25
25
  const outDir = fileURLToPath(dir);
26
26
  const urls = [];
@@ -44,16 +44,21 @@ export default function indexNow(options = {}) {
44
44
  }
45
45
  }
46
46
  walk(outDir);
47
- // KEEP EXISTING LOGGING
48
- console.log("[astro-indexnow] detected pages:");
47
+ logger.info("[astro-indexnow] detected pages:");
49
48
  for (const url of urls) {
50
- console.log(" -", url);
49
+ logger.info(` - ${url}`);
51
50
  }
52
51
  if (urls.length === 0) {
53
- console.log("[astro-indexnow] no pages detected, skipping submission");
52
+ logger.warn("[astro-indexnow] no pages detected, skipping submission");
54
53
  return;
55
54
  }
56
- // INDEXNOW SUBMISSION (new)
55
+ // Warn if key file is missing (do not block)
56
+ const keyFilePath = path.join(outDir, `${options.key}.txt`);
57
+ if (!fs.existsSync(keyFilePath)) {
58
+ logger.warn(`[astro-indexnow] Key file not found: /${options.key}.txt\n` +
59
+ "IndexNow may reject submissions until this file exists.");
60
+ }
61
+ // IndexNow submission
57
62
  try {
58
63
  const response = await fetch("https://api.indexnow.org/indexnow", {
59
64
  method: "POST",
@@ -68,13 +73,13 @@ export default function indexNow(options = {}) {
68
73
  }),
69
74
  });
70
75
  if (!response.ok) {
71
- console.warn(`[astro-indexnow] IndexNow request failed (${response.status})`);
76
+ logger.warn(`[astro-indexnow] IndexNow request failed (${response.status})`);
72
77
  return;
73
78
  }
74
- console.log(`[astro-indexnow] successfully submitted ${urls.length} URLs to IndexNow`);
79
+ logger.info(`[astro-indexnow] Successfully submitted ${urls.length} URLs to IndexNow`);
75
80
  }
76
- catch (err) {
77
- console.warn("[astro-indexnow] IndexNow submission failed (network error)");
81
+ catch {
82
+ logger.warn("[astro-indexnow] IndexNow submission failed (network error)");
78
83
  }
79
84
  },
80
85
  },
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "astro-indexnow",
3
- "version": "0.0.5",
4
- "description": "Astro integration to submit changed pages to IndexNow automatically",
3
+ "version": "1.0.0",
4
+ "description": "Astro integration to submit pages to IndexNow automatically after build",
5
5
  "type": "module",
6
6
  "exports": {
7
7
  ".": "./dist/index.js"
@@ -17,14 +17,28 @@
17
17
  "astro",
18
18
  "astro-integration",
19
19
  "indexnow",
20
- "seo"
20
+ "seo",
21
+ "search-engine",
22
+ "bing",
23
+ "yandex"
21
24
  ],
22
25
  "peerDependencies": {
23
26
  "astro": "^4.0.0 || ^5.0.0"
24
27
  },
25
28
  "devDependencies": {
26
29
  "@types/node": "^25.0.3",
27
- "astro-integration-kit": "^0.19.1",
28
30
  "typescript": "^5.0.0"
31
+ },
32
+ "repository": {
33
+ "type": "git",
34
+ "url": "https://github.com/velohost/astro-indexnow"
35
+ },
36
+ "homepage": "https://velohost.co.uk/tools/astro-indexnow",
37
+ "bugs": {
38
+ "url": "https://github.com/velohost/astro-indexnow/issues"
39
+ },
40
+ "license": "MIT",
41
+ "engines": {
42
+ "node": ">=18"
29
43
  }
30
44
  }