-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnext.config.js
More file actions
479 lines (462 loc) · 31.5 KB
/
Copy pathnext.config.js
File metadata and controls
479 lines (462 loc) · 31.5 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
})
/** @type {import('next').NextConfig} */
const isDesktop = process.env.TAURI_ENV === 'true';
const nextConfig = {
output: isDesktop ? 'export' : undefined,
trailingSlash: true,
compress: true,
poweredByHeader: false,
images: {
// Enable Next.js built-in image optimizer for WebP/AVIF conversion
// This is the single biggest LCP win — reduces image size 60-80% on mobile
formats: ['image/avif', 'image/webp'],
minimumCacheTTL: 2592000, // 30 days
deviceSizes: [375, 640, 750, 828, 1080, 1200, 1920],
imageSizes: [16, 32, 48, 64, 96, 128, 256, 384],
dangerouslyAllowSVG: true,
contentSecurityPolicy: "default-src 'self'; script-src 'none'; sandbox;",
},
async redirects() {
if (isDesktop) return [];
return [
// 404 Recovery (GSC Crawl Errors)
{ source: '/blog/headless-vs-traditional-cms', destination: '/blog/', permanent: true },
{ source: '/blog/headless-vs-traditional-cms/', destination: '/blog/', permanent: true },
{ source: '/blog/linear-vs-radial-vs-conic-gradients', destination: '/tools/css-generators/', permanent: true },
{ source: '/blog/linear-vs-radial-vs-conic-gradients/', destination: '/tools/css-generators/', permanent: true },
{ source: '/blog/pwa-development-guide', destination: '/blog/', permanent: true },
{ source: '/blog/pwa-development-guide/', destination: '/blog/', permanent: true },
{ source: '/blog/cloud-cost-management', destination: '/blog/', permanent: true },
{ source: '/blog/cloud-cost-management/', destination: '/blog/', permanent: true },
{ source: '/blog/regex-tester-tools-compared', destination: '/tools/regex-tester/', permanent: true },
{ source: '/blog/regex-tester-tools-compared/', destination: '/tools/regex-tester/', permanent: true },
{ source: '/blog/base64-encoding-use-cases', destination: '/tools/base64-encoder-decoder/', permanent: true },
{ source: '/blog/base64-encoding-use-cases/', destination: '/tools/base64-encoder-decoder/', permanent: true },
{ source: '/blog/favicon-psychology', destination: '/blog/', permanent: true },
{ source: '/blog/favicon-psychology/', destination: '/blog/', permanent: true },
{ source: '/blog/llms-txt-wordpress-guide', destination: '/blog/', permanent: true },
{ source: '/blog/llms-txt-wordpress-guide/', destination: '/blog/', permanent: true },
{ source: '/blog/diff-tools-for-wordpress', destination: '/blog/', permanent: true },
{ source: '/blog/diff-tools-for-wordpress/', destination: '/blog/', permanent: true },
{ source: '/blog/seo-schema-generator-2026-guide', destination: '/tools/schema-markup-generator/', permanent: true },
{ source: '/blog/seo-schema-generator-2026-guide/', destination: '/tools/schema-markup-generator/', permanent: true },
{ source: '/blog/professional-json-debugging-guide-2026', destination: '/tools/json-formatter/', permanent: true },
{ source: '/blog/professional-json-debugging-guide-2026/', destination: '/tools/json-formatter/', permanent: true },
{ source: '/blog/ai-coding-tools-2026', destination: '/blog/', permanent: true },
{ source: '/blog/ai-coding-tools-2026/', destination: '/blog/', permanent: true },
{ source: '/blog/serverless-computing-future', destination: '/blog/', permanent: true },
{ source: '/blog/serverless-computing-future/', destination: '/blog/', permanent: true },
{ source: '/blog/css-gradients-wordpress', destination: '/tools/css-generators/', permanent: true },
{ source: '/blog/css-gradients-wordpress/', destination: '/tools/css-generators/', permanent: true },
{ source: '/blog/typescript-best-practices-2026', destination: '/blog/', permanent: true },
{ source: '/blog/typescript-best-practices-2026/', destination: '/blog/', permanent: true },
// Wave 2 Consolidation
{ source: '/tools/schema-generator', destination: '/tools/schema-markup-generator/', permanent: true },
{ source: '/tools/schema-validator', destination: '/tools/schema-markup-generator/', permanent: true },
{ source: '/tools/schema-validator-pro', destination: '/tools/schema-markup-generator/', permanent: true },
{ source: '/tools/breadcrumb-schema', destination: '/tools/schema-markup-generator/', permanent: true },
{ source: '/tools/breadcrumb-schema-gen', destination: '/tools/schema-markup-generator/', permanent: true },
{ source: '/tools/qr-code-gen', destination: '/tools/qr-code-generator/', permanent: true },
{ source: '/tools/sql-formatter', destination: '/tools/sql-toolkit/', permanent: true },
// { source: '/tools/sql-minifier', destination: '/tools/sql-toolkit/', permanent: true },
{ source: '/tools/minify-sql', destination: '/tools/sql-minifier/', permanent: true },
{ source: '/tools/sql-injection-tester', destination: '/tools/sql-toolkit/', permanent: true },
{ source: '/tools/sql-sanitizer', destination: '/tools/sql-toolkit/', permanent: true },
{ source: '/tools/sql-injection-sanitizer', destination: '/tools/sql-toolkit/', permanent: true },
{ source: '/tools/markdown-to-html', destination: '/tools/markdown-html-converter/', permanent: true },
{ source: '/tools/markdown-converter', destination: '/tools/markdown-html-converter/', permanent: true },
{ source: '/tools/markdown-previewer', destination: '/tools/markdown-html-converter/', permanent: true },
{ source: '/tools/json-to-markdown', destination: '/tools/markdown-html-converter/', permanent: true },
{ source: '/tools/json-to-markdown/', destination: '/tools/markdown-html-converter/', permanent: true },
// Wave 3 Consolidation
{ source: '/tools/binary-converter', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/binary-to-decimal', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/decimal-to-binary', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/binary-to-hex', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/hex-to-binary', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/text-to-binary', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/binary-to-text', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/base64-encoder', destination: '/tools/base64-encoder-decoder/', permanent: true },
{ source: '/tools/base64-to-image', destination: '/tools/base64-encoder-decoder/', permanent: true },
{ source: '/tools/image-to-base64', destination: '/tools/base64-encoder-decoder/', permanent: true },
{ source: '/tools/case-converter', destination: '/tools/text-case-formatter/', permanent: true },
{ source: '/tools/title-case', destination: '/tools/text-case-formatter/', permanent: true },
{ source: '/tools/case-inverter', destination: '/tools/text-case-formatter/', permanent: true },
{ source: '/tools/text-reverser', destination: '/tools/text-case-formatter/', permanent: true },
{ source: '/tools/text-cleaner', destination: '/tools/text-case-formatter/', permanent: true },
{ source: '/tools/whitespace-remover', destination: '/tools/text-case-formatter/', permanent: true },
{ source: '/tools/duplicate-line-remover', destination: '/tools/text-case-formatter/', permanent: true },
{ source: '/tools/jwt-decoder', destination: '/tools/jwt-decoder-generator/', permanent: true },
{ source: '/tools/jwt-decoder/', destination: '/tools/jwt-decoder-generator/', permanent: true },
{ source: '/tools/jwt-signer', destination: '/tools/jwt-decoder-generator/', permanent: true },
{ source: '/tools/jwt-signer/', destination: '/tools/jwt-decoder-generator/', permanent: true },
{ source: '/tools/jwt-debugger', destination: '/tools/jwt-decoder-generator/', permanent: true },
{ source: '/tools/jwt-debugger/', destination: '/tools/jwt-decoder-generator/', permanent: true },
{ source: '/tools/alt-text-audit', destination: '/tools/alt-text-auditor/', permanent: true },
// Wave 4 Consolidation & Cleanup
{ source: '/tools/css-minifier', destination: '/tools/css-formatter-minifier/', permanent: true },
{ source: '/tools/css-formatter', destination: '/tools/css-formatter-minifier/', permanent: true },
{ source: '/tools/css-shadow-gen', destination: '/tools/css-generators/', permanent: true },
{ source: '/tools/css-keyframes', destination: '/tools/css-generators/', permanent: true },
{ source: '/tools/css-gradient-generator', destination: '/tools/css-generators/', permanent: true },
{ source: '/tools/header-inspector', destination: '/tools/http-headers-inspector/', permanent: true },
{ source: '/tools/cache-header-gen', destination: '/tools/http-headers-inspector/', permanent: true },
{ source: '/tools/robots-generator', destination: '/tools/robots-txt-toolkit/', permanent: true },
{ source: '/tools/robots-validator', destination: '/tools/robots-txt-toolkit/', permanent: true },
{ source: '/tools/robots-txt-templates', destination: '/tools/robots-txt-toolkit/', permanent: true },
{ source: '/tools/hex-to-rgb', destination: '/tools/color-converter/', permanent: true },
{ source: '/tools/rgba-to-hex', destination: '/tools/color-converter/', permanent: true },
{ source: '/tools/color-picker', destination: '/tools/color-converter/', permanent: true },
{ source: '/tools/px-to-rem', destination: '/tools/px-rem-converter/', permanent: true },
{ source: '/tools/rem-to-px', destination: '/tools/px-rem-converter/', permanent: true },
{ source: '/tools/browser-compat', destination: '/tools/browser-compat-checker/', permanent: true },
{ source: '/tools/authority-simulation', destination: '/tools/authority-simulator/', permanent: true },
{ source: '/tools/core-web-vitals-guide', destination: '/blog/core-web-vitals-guide/', permanent: true },
{ source: '/tools/seo-audit-checklist', destination: '/blog/seo-audit-checklist/', permanent: true },
// Tools Consolidation Redirects
{ source: '/tools/json-toolkit', destination: '/tools/json-to-code-generator', permanent: true },
{ source: '/tools/json-data-converter', destination: '/tools/json-yaml-jsonl-converter', permanent: true },
{ source: '/tools/uuid-generator', destination: '/tools/bulk-uuid-v4-v7-generator', permanent: true },
{ source: '/tools/password-suite', destination: '/tools/password-entropy-tester', permanent: true },
{ source: '/tools/data-converter', destination: '/tools/csv-json-xml-converter', permanent: true },
{ source: '/tools/csv-to-xml', destination: '/tools/csv-json-xml-converter', permanent: true },
{ source: '/tools/json-formatter-pro', destination: '/tools/json-formatter', permanent: true },
{ source: '/tools/json-to-ts', destination: '/tools/json-to-code-generator', permanent: true },
{ source: '/tools/json-to-go', destination: '/tools/json-to-code-generator', permanent: true },
{ source: '/tools/json-to-java', destination: '/tools/json-to-code-generator', permanent: true },
{ source: '/tools/json-to-pydantic', destination: '/tools/json-to-code-generator', permanent: true },
{ source: '/tools/json-to-prisma', destination: '/tools/json-to-code-generator', permanent: true },
{ source: '/tools/json-to-yaml', destination: '/tools/json-yaml-jsonl-converter', permanent: true },
{ source: '/tools/json-to-jsonl', destination: '/tools/json-yaml-jsonl-converter', permanent: true },
{ source: '/tools/uuid-v4-gen', destination: '/tools/bulk-uuid-v4-v7-generator', permanent: true },
{ source: '/tools/uuid-v7-generator', destination: '/tools/bulk-uuid-v4-v7-generator', permanent: true },
{ source: '/tools/password-generator', destination: '/tools/password-entropy-tester', permanent: true },
{ source: '/tools/password-auditor', destination: '/tools/password-entropy-tester', permanent: true },
{ source: '/tools/password-tester', destination: '/tools/password-entropy-tester', permanent: true },
{ source: '/tools/xml-to-csv', destination: '/tools/csv-json-xml-converter', permanent: true },
{ source: '/tools/json-to-csv', destination: '/tools/csv-json-xml-converter', permanent: true },
{ source: '/tools/csv-to-json', destination: '/tools/csv-json-xml-converter', permanent: true },
{ source: '/tools/xml-to-json', destination: '/tools/csv-json-xml-converter', permanent: true },
{ source: '/tools/json-to-xml', destination: '/tools/csv-json-xml-converter', permanent: true },
{
source: '/blog/iran-conflict-2026-cybersecurity/',
destination: '/blog/enterprise-web-security-guide/',
permanent: true,
},
{
source: '/blog/lirr-strike-2026-remote-dev-tools',
destination: '/blog/ai-first-development-2026/',
permanent: true,
},
{
source: '/blog/lirr-strike-2026-remote-dev-tools/',
destination: '/blog/ai-first-development-2026/',
permanent: true,
},
{
source: '/blog/trump-xi-summit-2026-tech-impact',
destination: '/blog/edge-computing-guide/',
permanent: true,
},
{
source: '/blog/trump-xi-summit-2026-tech-impact/',
destination: '/blog/edge-computing-guide/',
permanent: true,
},
{
source: '/blog/supreme-court-2026-privacy-impact',
destination: '/blog/privacy-first-web-development/',
permanent: true,
},
{
source: '/blog/supreme-court-2026-privacy-impact/',
destination: '/blog/privacy-first-web-development/',
permanent: true,
},
// Cuts and Merges (July 2026 consolidation)
{ source: '/blog/ai-coding-tools-2026', destination: '/blog/', permanent: true },
{ source: '/blog/ai-coding-tools-2026/', destination: '/blog/', permanent: true },
{ source: '/blog/ai-cybersecurity-trends', destination: '/blog/', permanent: true },
{ source: '/blog/ai-cybersecurity-trends/', destination: '/blog/', permanent: true },
{ source: '/blog/ai-in-devops-future', destination: '/blog/', permanent: true },
{ source: '/blog/ai-in-devops-future/', destination: '/blog/', permanent: true },
{ source: '/blog/ai-web-dev-workflows-2026', destination: '/blog/', permanent: true },
{ source: '/blog/ai-web-dev-workflows-2026/', destination: '/blog/', permanent: true },
{ source: '/blog/typescript-best-practices-2026', destination: '/blog/', permanent: true },
{ source: '/blog/typescript-best-practices-2026/', destination: '/blog/', permanent: true },
{ source: '/blog/ui-ux-design-trends', destination: '/blog/', permanent: true },
{ source: '/blog/ui-ux-design-trends/', destination: '/blog/', permanent: true },
{ source: '/blog/serverless-computing-future', destination: '/blog/', permanent: true },
{ source: '/blog/serverless-computing-future/', destination: '/blog/', permanent: true },
{ source: '/blog/automated-testing-guide', destination: '/blog/', permanent: true },
{ source: '/blog/automated-testing-guide/', destination: '/blog/', permanent: true },
{ source: '/blog/scalable-database-design', destination: '/blog/', permanent: true },
{ source: '/blog/scalable-database-design/', destination: '/blog/', permanent: true },
{ source: '/blog/enterprise-js-frameworks', destination: '/blog/', permanent: true },
{ source: '/blog/enterprise-js-frameworks/', destination: '/blog/', permanent: true },
{ source: '/blog/how-to-fix-common-json-errors', destination: '/blog/professional-json-debugging-guide-2026/', permanent: true },
{ source: '/blog/how-to-fix-common-json-errors/', destination: '/blog/professional-json-debugging-guide-2026/', permanent: true },
{ source: '/blog/json-formatting-best-practices', destination: '/blog/professional-json-debugging-guide-2026/', permanent: true },
{ source: '/blog/json-formatting-best-practices/', destination: '/blog/professional-json-debugging-guide-2026/', permanent: true },
{ source: '/blog/json-ld-evolution-2026', destination: '/blog/json-ld-schema-tutorial/', permanent: true },
{ source: '/blog/json-ld-evolution-2026/', destination: '/blog/json-ld-schema-tutorial/', permanent: true },
{ source: '/blog/jwt-security-guide', destination: '/blog/jwt-security-best-practices/', permanent: true },
{ source: '/blog/jwt-security-guide/', destination: '/blog/jwt-security-best-practices/', permanent: true },
{ source: '/blog/regex-patterns-every-developer-should-know', destination: '/blog/regex-cheat-sheet-javascript/', permanent: true },
{ source: '/blog/regex-patterns-every-developer-should-know/', destination: '/blog/regex-cheat-sheet-javascript/', permanent: true },
{ source: '/blog/20-must-know-regex-patterns', destination: '/blog/regex-cheat-sheet-javascript/', permanent: true },
{ source: '/blog/20-must-know-regex-patterns/', destination: '/blog/regex-cheat-sheet-javascript/', permanent: true },
{ source: '/blog/password-security-guide', destination: '/blog/password-security-enterprise-2026/', permanent: true },
{ source: '/blog/password-security-guide/', destination: '/blog/password-security-enterprise-2026/', permanent: true },
{ source: '/blog/geo-optimization-guide', destination: '/blog/geo-future-of-seo/', permanent: true },
{ source: '/blog/geo-optimization-guide/', destination: '/blog/geo-future-of-seo/', permanent: true },
{ source: '/blog/ai-seo-optimization-2026', destination: '/blog/geo-future-of-seo/', permanent: true },
{ source: '/blog/ai-seo-optimization-2026/', destination: '/blog/geo-future-of-seo/', permanent: true },
{ source: '/blog/edge-computing-performance-2026', destination: '/blog/edge-computing-guide/', permanent: true },
{ source: '/blog/edge-computing-performance-2026/', destination: '/blog/edge-computing-guide/', permanent: true },
{ source: '/blog/edge-computing-core-web-vitals', destination: '/blog/edge-computing-guide/', permanent: true },
{ source: '/blog/edge-computing-core-web-vitals/', destination: '/blog/edge-computing-guide/', permanent: true },
{ source: '/blog/server-first-rendering-2026', destination: '/blog/server-first-vs-client-rendering-2026/', permanent: true },
{ source: '/blog/server-first-rendering-2026/', destination: '/blog/server-first-vs-client-rendering-2026/', permanent: true },
{ source: '/blog/cron-expression-examples', destination: '/blog/cron-expression-generator-2026/', permanent: true },
{ source: '/blog/cron-expression-examples/', destination: '/blog/cron-expression-generator-2026/', permanent: true },
{ source: '/blog/llms-txt-generator-guide', destination: '/blog/what-is-llms-txt/', permanent: true },
{ source: '/blog/llms-txt-generator-guide/', destination: '/blog/what-is-llms-txt/', permanent: true },
// Ahrefs 404 Fixes (June 2026)
{ source: '/tools/base64-encode-decode', destination: '/tools/base64-encoder-decoder/', permanent: true },
{ source: '/tools/base64-encode-decode/', destination: '/tools/base64-encoder-decoder/', permanent: true },
{ source: '/blog/what-is-sha256-hashing', destination: '/tools/hash-generator/', permanent: true },
{ source: '/blog/what-is-sha256-hashing/', destination: '/tools/hash-generator/', permanent: true },
{ source: '/tools/nginx-config-generator', destination: '/tools/nginx-generator/', permanent: true },
{ source: '/tools/nginx-config-generator/', destination: '/tools/nginx-generator/', permanent: true },
{ source: '/tools/url-encoder-decoder', destination: '/tools/url-encoder/', permanent: true },
{ source: '/tools/url-encoder-decoder/', destination: '/tools/url-encoder/', permanent: true },
{ source: '/tools/hsts-generator', destination: '/tools/hsts-gen/', permanent: true },
{ source: '/tools/hsts-generator/', destination: '/tools/hsts-gen/', permanent: true },
{ source: '/tools/robots-txt-generator', destination: '/tools/robots-txt-toolkit/', permanent: true },
{ source: '/tools/robots-txt-generator/', destination: '/tools/robots-txt-toolkit/', permanent: true },
{ source: '/blog/rsa-key-pair-generator', destination: '/tools/rsa-key-gen/', permanent: true },
{ source: '/blog/rsa-key-pair-generator/', destination: '/tools/rsa-key-gen/', permanent: true },
{ source: '/tools/meta-tags-generator', destination: '/tools/meta-tag-generator/', permanent: true },
{ source: '/tools/meta-tags-generator/', destination: '/tools/meta-tag-generator/', permanent: true },
{ source: '/blog/markdown-vs-html-content', destination: '/tools/markdown-html-converter/', permanent: true },
{ source: '/blog/markdown-vs-html-content/', destination: '/tools/markdown-html-converter/', permanent: true },
{ source: '/old-page', destination: '/', permanent: true },
{ source: '/old-page/', destination: '/', permanent: true },
{ source: '/old-docs/:slug*', destination: '/tools/', permanent: true },
{ source: '/services/modern-endpoint', destination: '/', permanent: true },
{ source: '/services/modern-endpoint/', destination: '/', permanent: true },
{ source: '/index.html', destination: '/', permanent: true },
{ source: '/login', destination: '/', permanent: true },
{ source: '/login/', destination: '/', permanent: true },
{ source: '/deals/\\$1;', destination: '/', permanent: true },
{ source: '/deals/\\$1;/', destination: '/', permanent: true },
{ source: '/assets/og-image.jpg', destination: '/og-image.jpg', permanent: true },
{ source: '/blog/:path*.jpg', destination: '/og-image.jpg', permanent: true },
{
source: '/tools/category/:category',
destination: '/tools/hub/:category/',
permanent: true,
},
{
source: '/tools/uuid-v7',
destination: '/tools/bulk-uuid-v4-v7-generator/',
permanent: true,
},
{
source: '/tools/uuid-v7/',
destination: '/tools/bulk-uuid-v4-v7-generator/',
permanent: true,
},
{
source: '/tools/password-strength-tester',
destination: '/tools/password-entropy-tester/',
permanent: true,
},
{
source: '/tools/password-strength-tester/',
destination: '/tools/password-entropy-tester/',
permanent: true,
},
{
source: '/tools/yaml-formatter',
destination: '/tools/yaml-to-json/',
permanent: true,
},
{
source: '/tools/yaml-formatter/',
destination: '/tools/yaml-to-json/',
permanent: true,
},
// GSC 404 Renamed Tool Mappings (June 2026)
{ source: '/tools/sql-injection-sanitizer', destination: '/tools/xss-scanner/', permanent: true },
{ source: '/tools/sql-injection-sanitizer/', destination: '/tools/xss-scanner/', permanent: true },
{ source: '/tools/css-color-extractor', destination: '/tools/color-converter/', permanent: true },
{ source: '/tools/css-color-extractor/', destination: '/tools/color-converter/', permanent: true },
{ source: '/tools/binary-to-hex', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/binary-to-hex/', destination: '/tools/binary-hex-decimal-converter/', permanent: true },
{ source: '/tools/xml-to-json', destination: '/tools/csv-json-xml-converter/', permanent: true },
{ source: '/tools/xml-to-json/', destination: '/tools/csv-json-xml-converter/', permanent: true },
{ source: '/tools/cdn-finder', destination: '/tools/cdn-readiness-tester/', permanent: true },
{ source: '/tools/cdn-finder/', destination: '/tools/cdn-readiness-tester/', permanent: true },
{ source: '/tools/alt-text-audit', destination: '/tools/alt-text-auditor/', permanent: true },
{ source: '/tools/alt-text-audit/', destination: '/tools/alt-text-auditor/', permanent: true },
{ source: '/tools/json-to-jsonl', destination: '/tools/json-yaml-jsonl-converter/', permanent: true },
{ source: '/tools/json-to-jsonl/', destination: '/tools/json-yaml-jsonl-converter/', permanent: true },
{ source: '/tools/password-auditor', destination: '/tools/password-entropy-tester/', permanent: true },
{ source: '/tools/password-auditor/', destination: '/tools/password-entropy-tester/', permanent: true },
{ source: '/tools/px-to-rem', destination: '/tools/px-rem-converter/', permanent: true },
{ source: '/tools/px-to-rem/', destination: '/tools/px-rem-converter/', permanent: true },
{ source: '/tools/robots-txt-templates', destination: '/tools/robots-txt-toolkit/', permanent: true },
{ source: '/tools/robots-txt-templates/', destination: '/tools/robots-txt-toolkit/', permanent: true },
{ source: '/tools/contrast-checker', destination: '/tools/color-contrast/', permanent: true },
{ source: '/tools/contrast-checker/', destination: '/tools/color-contrast/', permanent: true },
{ source: '/tools/json-to-markdown', destination: '/tools/json-to-code-generator/', permanent: true },
{ source: '/tools/json-to-markdown/', destination: '/tools/json-to-code-generator/', permanent: true },
// Content Audit Thin Article Merges (June 2026)
{ source: '/blog/json-to-pydantic-model-generator', destination: '/blog/what-is-json-complete-guide/', permanent: true },
{ source: '/blog/json-to-pydantic-model-generator/', destination: '/blog/what-is-json-complete-guide/', permanent: true },
{ source: '/blog/json-to-typescript-interface-converter', destination: '/blog/what-is-json-complete-guide/', permanent: true },
{ source: '/blog/json-to-typescript-interface-converter/', destination: '/blog/what-is-json-complete-guide/', permanent: true },
{ source: '/blog/css-box-shadow-generator-examples', destination: '/blog/25-free-developer-tools-bookmark/', permanent: true },
{ source: '/blog/css-box-shadow-generator-examples/', destination: '/blog/25-free-developer-tools-bookmark/', permanent: true },
{ source: '/blog/css-gradient-generator-linear-radial', destination: '/blog/25-free-developer-tools-bookmark/', permanent: true },
{ source: '/blog/css-gradient-generator-linear-radial/', destination: '/blog/25-free-developer-tools-bookmark/', permanent: true },
{ source: '/blog/generate-jwt-token-online-free', destination: '/blog/what-is-jwt-complete-guide/', permanent: true },
{ source: '/blog/generate-jwt-token-online-free/', destination: '/blog/what-is-jwt-complete-guide/', permanent: true },
// SEO Audit 2026: Merged Thin Content Redirects
{ source: '/tools/uk-dashboard', destination: '/tools/hub/', permanent: true },
{ source: '/tools/uk-dashboard/', destination: '/tools/hub/', permanent: true },
{
source: '/:path*',
has: [{ type: 'host', value: 'www.wtkpro.site' }],
destination: 'https://wtkpro.site/:path*',
permanent: true,
},
{
source: '/:path*',
has: [{ type: 'host', value: 'wtkpro-hub.vercel.app' }],
destination: 'https://wtkpro.site/:path*',
permanent: true,
},
{
source: '/:path*',
has: [{ type: 'host', value: 'webtoolkit-pro.vercel.app' }],
destination: 'https://wtkpro.site/:path*',
permanent: true,
},
]
},
// Ensure long-term caching for static assets and security hardening
async headers() {
const securityHeaders = [
{
key: 'X-Frame-Options',
value: 'SAMEORIGIN',
},
{
key: 'X-Content-Type-Options',
value: 'nosniff',
},
{
key: 'Referrer-Policy',
value: 'strict-origin-when-cross-origin',
},
{
key: 'Content-Security-Policy',
value: "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' blob: https://cdn.jsdelivr.net https://pagead2.googlesyndication.com https://www.googletagmanager.com https://www.google-analytics.com https://adservice.google.com https://va.vercel-scripts.com https://static.cloudflareinsights.com https://vercel.live https://ep2.adtrafficquality.google https://*.google.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com https://cdn.jsdelivr.net; img-src 'self' data: https://pagead2.googlesyndication.com https://www.google-analytics.com https://adservice.google.com https://*.google.com https://*.gstatic.com https://ep1.adtrafficquality.google https://vercel.com https://vercel.live; font-src 'self' https://fonts.gstatic.com https://cdn.jsdelivr.net https://vercel.live; connect-src 'self' https://wtkpro.site https://www.wtkpro.site https://www.google-analytics.com https://stats.g.doubleclick.net https://pagead2.googlesyndication.com https://vitals.vercel-insights.com https://ep1.adtrafficquality.google https://ep2.adtrafficquality.google https://vercel.live https://cdn.jsdelivr.net https://static.cloudflareinsights.com https://www.googletagmanager.com https://*.google.com https://analytics.google.com wss://*.pusher.com; frame-src 'self' https://googleads.g.doubleclick.net https://*.google.com https://vercel.live https://ep2.adtrafficquality.google; worker-src 'self' blob:; object-src 'none'; upgrade-insecure-requests;",
},
{
key: 'Permissions-Policy',
value: 'camera=(), microphone=(), geolocation=()',
},
{
key: 'Strict-Transport-Security',
value: 'max-age=31536000; includeSubDomains; preload',
},
{
key: 'X-XSS-Protection',
value: '1; mode=block',
},
{
key: 'Cache-Control',
value: 'no-transform',
},
{
key: 'X-402-Facilitator',
value: 'https://stripe.com',
},
{
key: 'X-402-Wallet',
value: 'acct_1032D82eB69zArt5',
},
]
if (isDesktop) return [];
return [
{
source: '/',
headers: [
...securityHeaders,
{
key: 'Link',
value: '</llms.txt>; rel="describedby"'
}
]
},
{
source: '/:path*',
headers: securityHeaders,
},
{
// Kill-switch SW: never cache, always fetch fresh so browsers pick up the unregister immediately
source: '/sw.js',
headers: [
{ key: 'Cache-Control', value: 'no-cache, no-store, must-revalidate' },
{ key: 'Service-Worker-Allowed', value: '/' },
],
},
{
// Static assets: 30-day cache with stale-while-revalidate
source: '/:path*((?!robots\\.txt|sitemap\\.xml).+\\.(?:webp|avif|png|jpg|jpeg|ico|svg|woff2|woff|ttf))',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=2592000, stale-while-revalidate=86400, immutable',
},
],
},
{
// JS/CSS bundles: long cache (Next.js hashes filenames)
source: '/_next/static/:path*',
headers: [
{
key: 'Cache-Control',
value: 'public, max-age=31536000, immutable',
},
],
},
]
},
webpack: (config, { isServer }) => {
config.experiments = {
...config.experiments,
asyncWebAssembly: true,
}
if (!isServer) {
config.resolve.fallback = {
...config.resolve.fallback,
fs: false,
path: false,
child_process: false,
}
}
return config
},
experimental: {
optimizeCss: true,
optimizePackageImports: ['lucide-react'],
}
}
module.exports = withBundleAnalyzer(nextConfig)