feat: Implement a client-side barcode generator tool and integrate IndexNow API for site URL submission.

This commit is contained in:
Timo Knuth 2026-01-21 22:39:04 +01:00
parent cca1374c9e
commit 896c9b1a07
3 changed files with 39 additions and 27 deletions

View File

@ -150,18 +150,20 @@ export default function BarcodeGeneratorClient() {
{/* Configuration */} {/* Configuration */}
<div className="space-y-6"> <div className="space-y-6">
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2"> <h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
<Sliders className="w-5 h-5 text-slate-900" /> <Sliders className="w-5 h-5 text-slate-900" aria-hidden="true" />
Configuration Configuration
</h2> </h2>
<div className="space-y-4"> <div className="space-y-4">
<div> <div>
<label className="block text-sm font-medium text-slate-700 mb-2">Content</label> <label htmlFor="barcode-content" className="block text-sm font-medium text-slate-700 mb-2">Content</label>
<Input <Input
id="barcode-content"
value={value} value={value}
onChange={(e) => setValue(e.target.value)} onChange={(e) => setValue(e.target.value)}
placeholder="Enter barcode data (e.g. 12345678)" placeholder="Enter barcode data (e.g. 12345678)"
className="h-12 text-base rounded-xl border-slate-200 focus:border-slate-900 focus:ring-slate-900" className="h-12 text-base rounded-xl border-slate-200 focus:border-slate-900 focus:ring-slate-900"
aria-label="Barcode content"
/> />
</div> </div>
@ -195,17 +197,18 @@ export default function BarcodeGeneratorClient() {
{/* Design Options */} {/* Design Options */}
<div className="space-y-6"> <div className="space-y-6">
<h2 className="text-lg font-bold text-slate-900 flex items-center gap-2"> <h2 className="text-lg font-bold text-slate-900 flex items-center gap-2">
<Sparkles className="w-5 h-5 text-slate-900" /> <Sparkles className="w-5 h-5 text-slate-900" aria-hidden="true" />
Design Options Design Options
</h2> </h2>
<div className="grid grid-cols-2 gap-6"> <div className="grid grid-cols-2 gap-6">
<div className="space-y-3"> <div className="space-y-3">
<div className="flex justify-between"> <div className="flex justify-between">
<label className="text-sm font-medium text-slate-700">Width</label> <label htmlFor="width-range" className="text-sm font-medium text-slate-700">Width</label>
<span className="text-xs text-slate-500 bg-slate-100 px-2 py-1 rounded-md font-bold">{width}px</span> <span className="text-xs text-slate-500 bg-slate-100 px-2 py-1 rounded-md font-bold">{width}px</span>
</div> </div>
<input <input
id="width-range"
type="range" type="range"
min="1" min="1"
max="4" max="4"
@ -213,15 +216,17 @@ export default function BarcodeGeneratorClient() {
value={width} value={width}
onChange={(e) => setWidth(parseFloat(e.target.value))} onChange={(e) => setWidth(parseFloat(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900" className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900"
aria-label="Barcode width"
/> />
</div> </div>
<div className="space-y-3"> <div className="space-y-3">
<div className="flex justify-between"> <div className="flex justify-between">
<label className="text-sm font-medium text-slate-700">Height</label> <label htmlFor="height-range" className="text-sm font-medium text-slate-700">Height</label>
<span className="text-xs text-slate-500 bg-slate-100 px-2 py-1 rounded-md font-bold">{height}px</span> <span className="text-xs text-slate-500 bg-slate-100 px-2 py-1 rounded-md font-bold">{height}px</span>
</div> </div>
<input <input
id="height-range"
type="range" type="range"
min="30" min="30"
max="200" max="200"
@ -229,6 +234,7 @@ export default function BarcodeGeneratorClient() {
value={height} value={height}
onChange={(e) => setHeight(parseInt(e.target.value))} onChange={(e) => setHeight(parseInt(e.target.value))}
className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900" className="w-full h-2 bg-slate-200 rounded-lg appearance-none cursor-pointer accent-slate-900"
aria-label="Barcode height"
/> />
</div> </div>
</div> </div>
@ -245,10 +251,10 @@ export default function BarcodeGeneratorClient() {
lineColor === c.value ? "border-slate-900 ring-2 ring-offset-2 ring-slate-200" : "border-white shadow-md" lineColor === c.value ? "border-slate-900 ring-2 ring-offset-2 ring-slate-200" : "border-white shadow-md"
)} )}
style={{ backgroundColor: c.value }} style={{ backgroundColor: c.value }}
aria-label={`Select ${c.name}`} aria-label={`Select color ${c.name}`}
title={c.name} title={c.name}
> >
{lineColor === c.value && <Check className="w-4 h-4 text-white" strokeWidth={3} />} {lineColor === c.value && <Check className="w-4 h-4 text-white" strokeWidth={3} aria-hidden="true" />}
</button> </button>
))} ))}
</div> </div>
@ -361,8 +367,9 @@ export default function BarcodeGeneratorClient() {
<Button <Button
onClick={() => downloadBarcode('png')} onClick={() => downloadBarcode('png')}
className="w-full sm:flex-1 bg-slate-900 hover:bg-black text-white shadow-lg h-12 rounded-xl" className="w-full sm:flex-1 bg-slate-900 hover:bg-black text-white shadow-lg h-12 rounded-xl"
aria-label="Download barcode as PNG"
> >
<Download className="w-4 h-4 mr-2" /> <Download className="w-4 h-4 mr-2" aria-hidden="true" />
Download PNG Download PNG
</Button> </Button>
<div className="relative w-full sm:w-auto"> <div className="relative w-full sm:w-auto">
@ -373,6 +380,7 @@ export default function BarcodeGeneratorClient() {
onClick={() => downloadBarcode('svg')} onClick={() => downloadBarcode('svg')}
variant="outline" variant="outline"
className="w-full sm:w-auto px-6 border-slate-300 hover:bg-white h-12 rounded-xl font-bold" className="w-full sm:w-auto px-6 border-slate-300 hover:bg-white h-12 rounded-xl font-bold"
aria-label="Download barcode as SVG"
> >
SVG SVG
</Button> </Button>
@ -382,16 +390,18 @@ export default function BarcodeGeneratorClient() {
variant="outline" variant="outline"
className="w-full sm:w-auto px-4 border-slate-300 hover:bg-white h-12 rounded-xl" className="w-full sm:w-auto px-4 border-slate-300 hover:bg-white h-12 rounded-xl"
title="Copy to Clipboard" title="Copy to Clipboard"
aria-label="Copy barcode image to clipboard"
> >
<Copy className="w-4 h-4 text-slate-600" /> <Copy className="w-4 h-4 text-slate-600" aria-hidden="true" />
</Button> </Button>
<Button <Button
onClick={() => window.print()} onClick={() => window.print()}
variant="outline" variant="outline"
className="w-full sm:w-auto px-4 border-slate-300 hover:bg-white h-12 rounded-xl" className="w-full sm:w-auto px-4 border-slate-300 hover:bg-white h-12 rounded-xl"
title="Print" title="Print"
aria-label="Print barcode"
> >
<Printer className="w-4 h-4 text-slate-600" /> <Printer className="w-4 h-4 text-slate-600" aria-hidden="true" />
</Button> </Button>
</div> </div>

View File

@ -28,13 +28,15 @@ export function BarcodeGuide() {
src="/barcode-generator-preview.png" src="/barcode-generator-preview.png"
alt="Free Online Barcode Generator Preview - Create EAN, UPC, and Code 128 Barcodes" alt="Free Online Barcode Generator Preview - Create EAN, UPC, and Code 128 Barcodes"
className="w-full h-64 sm:h-80 object-cover" className="w-full h-64 sm:h-80 object-cover"
width="800"
height="320"
/> />
<div className="bg-slate-50 p-4 text-sm text-slate-500 text-center border-t border-slate-100"> <div className="bg-slate-50 p-4 text-sm text-slate-500 text-center border-t border-slate-100">
Use our <strong>free barcode generator</strong> to create scannable codes. Use our <strong>free barcode generator</strong> to create scannable codes.
</div> </div>
</div> </div>
<h3>What Is a Barcode?</h3> <h2>What Is a Barcode?</h2>
<p> <p>
A barcode is a visual representation of data that can be read by machines. It consists of vertical lines with different widths and spacing, which encode numbers or characters. When scanned with a barcode scanner or smartphone, the information is instantly translated into readable data. A barcode is a visual representation of data that can be read by machines. It consists of vertical lines with different widths and spacing, which encode numbers or characters. When scanned with a barcode scanner or smartphone, the information is instantly translated into readable data.
</p> </p>
@ -42,7 +44,7 @@ export function BarcodeGuide() {
Barcodes are commonly used to identify products, track inventory, manage logistics, and speed up checkout processes. They reduce manual input and significantly lower the risk of human error. Barcodes are commonly used to identify products, track inventory, manage logistics, and speed up checkout processes. They reduce manual input and significantly lower the risk of human error.
</p> </p>
<h3>How Does a Barcode Generator Work?</h3> <h2>How Does a Barcode Generator Work?</h2>
<p> <p>
A Barcode Generator converts text or numeric input into a barcode format that scanners can read. The process is simple: A Barcode Generator converts text or numeric input into a barcode format that scanners can read. The process is simple:
</p> </p>
@ -80,7 +82,7 @@ export function BarcodeGuide() {
A modern <strong>Barcode Generator</strong> works directly in the browser and does not require additional software. A modern <strong>Barcode Generator</strong> works directly in the browser and does not require additional software.
</p> </p>
<h3>Common Types of Barcodes</h3> <h2>Common Types of Barcodes</h2>
<p> <p>
Different barcode formats are used for different purposes. Choosing the right one is important for compatibility and scanning accuracy. Different barcode formats are used for different purposes. Choosing the right one is important for compatibility and scanning accuracy.
</p> </p>
@ -94,7 +96,7 @@ export function BarcodeGuide() {
</div> </div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Retail Europe</div> <div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Retail Europe</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center"> <div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="EAN-13 Barcode Sample for International Products" className="h-10 object-contain opacity-75 grayscale" /> <img src="/barcode-generator-preview.png" alt="EAN-13 Barcode Sample for International Products" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div> </div>
<p className="text-sm text-slate-600 m-0"> <p className="text-sm text-slate-600 m-0">
EAN-13 is widely used in retail, especially in Europe. It is designed for consumer products sold in stores and supermarkets. EAN-13 is widely used in retail, especially in Europe. It is designed for consumer products sold in stores and supermarkets.
@ -109,7 +111,7 @@ export function BarcodeGuide() {
</div> </div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Retail USA/Canada</div> <div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Retail USA/Canada</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center"> <div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="UPC-A Barcode Example for Retail Products in USA" className="h-10 object-contain opacity-75 grayscale" /> <img src="/barcode-generator-preview.png" alt="UPC-A Barcode Example for Retail Products in USA" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div> </div>
<p className="text-sm text-slate-600 m-0"> <p className="text-sm text-slate-600 m-0">
UPC-A is similar to EAN-13 but is mainly used in the United States and Canada for retail products. UPC-A is similar to EAN-13 but is mainly used in the United States and Canada for retail products.
@ -124,7 +126,7 @@ export function BarcodeGuide() {
</div> </div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Logistics Universal</div> <div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Logistics Universal</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center"> <div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="Code 128 Barcode for Inventory and Shipping Labels" className="h-10 object-contain opacity-75 grayscale" /> <img src="/barcode-generator-preview.png" alt="Code 128 Barcode for Inventory and Shipping Labels" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div> </div>
<p className="text-sm text-slate-600 m-0"> <p className="text-sm text-slate-600 m-0">
Code 128 is a flexible barcode format that supports letters and numbers. It is commonly used in logistics, shipping, and internal tracking systems. Code 128 is a flexible barcode format that supports letters and numbers. It is commonly used in logistics, shipping, and internal tracking systems.
@ -139,7 +141,7 @@ export function BarcodeGuide() {
</div> </div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Industrial Military</div> <div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Industrial Military</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center"> <div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="Code 39 Barcode for Industrial Use" className="h-10 object-contain opacity-75 grayscale" /> <img src="/barcode-generator-preview.png" alt="Code 39 Barcode for Industrial Use" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div> </div>
<p className="text-sm text-slate-600 m-0"> <p className="text-sm text-slate-600 m-0">
The first alphanumeric barcode, Code 39 is still widely used in automotive and defense industries. It supports numbers and uppercase letters. The first alphanumeric barcode, Code 39 is still widely used in automotive and defense industries. It supports numbers and uppercase letters.
@ -154,7 +156,7 @@ export function BarcodeGuide() {
</div> </div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Inventory Shelves</div> <div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Inventory Shelves</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center"> <div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="MSI Barcode for Inventory Management" className="h-10 object-contain opacity-75 grayscale" /> <img src="/barcode-generator-preview.png" alt="MSI Barcode for Inventory Management" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div> </div>
<p className="text-sm text-slate-600 m-0"> <p className="text-sm text-slate-600 m-0">
MSI (Modified Plessey) is often used for inventory control in retail environments, such as labeling shelves in supermarkets and warehouses. MSI (Modified Plessey) is often used for inventory control in retail environments, such as labeling shelves in supermarkets and warehouses.
@ -169,7 +171,7 @@ export function BarcodeGuide() {
</div> </div>
<div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Pharma Packaging</div> <div className="text-xs font-mono bg-slate-100 inline-block px-2 py-1 rounded text-slate-500 mb-3">Pharma Packaging</div>
<div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center"> <div className="mb-3 bg-slate-50 rounded border border-slate-100 p-2 flex justify-center">
<img src="/barcode-generator-preview.png" alt="Pharmacode for Pharmaceutical Packaging" className="h-10 object-contain opacity-75 grayscale" /> <img src="/barcode-generator-preview.png" alt="Pharmacode for Pharmaceutical Packaging" className="h-10 object-contain opacity-75 grayscale" width="200" height="40" />
</div> </div>
<p className="text-sm text-slate-600 m-0"> <p className="text-sm text-slate-600 m-0">
Pharmacode is a specialized barcode standard used in the pharmaceutical industry for packaging control to prevent medication errors. Pharmacode is a specialized barcode standard used in the pharmaceutical industry for packaging control to prevent medication errors.
@ -179,7 +181,7 @@ export function BarcodeGuide() {
</div> </div>
<h3>Why Use a Barcode Generator?</h3> <h2>Why Use a Barcode Generator?</h2>
<p>Using a Barcode Generator offers several advantages:</p> <p>Using a Barcode Generator offers several advantages:</p>
<div className="not-prose grid gap-4 mb-8"> <div className="not-prose grid gap-4 mb-8">
<div className="flex gap-4 items-start"> <div className="flex gap-4 items-start">
@ -215,7 +217,7 @@ export function BarcodeGuide() {
For small businesses, online shops, and startups, a <strong>free Barcode Generator</strong> is often the easiest way to get started. For small businesses, online shops, and startups, a <strong>free Barcode Generator</strong> is often the easiest way to get started.
</p> </p>
<h3>Barcode vs QR Code</h3> <h2>Barcode vs QR Code</h2>
<p> <p>
Although barcodes and QR codes are often confused, they serve different purposes. A barcode stores data horizontally and is mainly used for product identification. A <Link href="/tools/url-qr-code" className="text-blue-600 hover:underline">QR code</Link> stores data both horizontally and vertically and can contain more complex information such as URLs or <Link href="/tools/vcard-qr-code" className="text-blue-600 hover:underline">contact details</Link>. Although barcodes and QR codes are often confused, they serve different purposes. A barcode stores data horizontally and is mainly used for product identification. A <Link href="/tools/url-qr-code" className="text-blue-600 hover:underline">QR code</Link> stores data both horizontally and vertically and can contain more complex information such as URLs or <Link href="/tools/vcard-qr-code" className="text-blue-600 hover:underline">contact details</Link>.
</p> </p>
@ -223,7 +225,7 @@ export function BarcodeGuide() {
If you only need to identify products or inventory items, a classic barcode is usually the better choice. If you only need to identify products or inventory items, a classic barcode is usually the better choice.
</p> </p>
<h3>Are Barcodes Free to Use?</h3> <h2>Are Barcodes Free to Use?</h2>
<p> <p>
The barcode image itself can be generated for free using a Barcode Generator. However, for retail products sold internationally, the barcode number may need to be officially registered through organizations such as GS1. This ensures that the barcode is unique and recognized globally. The barcode image itself can be generated for free using a Barcode Generator. However, for retail products sold internationally, the barcode number may need to be officially registered through organizations such as GS1. This ensures that the barcode is unique and recognized globally.
</p> </p>
@ -231,7 +233,7 @@ export function BarcodeGuide() {
For internal use, testing, or small projects, free barcode generation is usually sufficient. For internal use, testing, or small projects, free barcode generation is usually sufficient.
</p> </p>
<h3>Use Cases for Barcodes</h3> <h2>Use Cases for Barcodes</h2>
<p>Barcodes are used in many industries, including:</p> <p>Barcodes are used in many industries, including:</p>
<ul className="list-disc pl-6 space-y-2 mb-8"> <ul className="list-disc pl-6 space-y-2 mb-8">
<li>Retail and e-commerce</li> <li>Retail and e-commerce</li>
@ -244,12 +246,12 @@ export function BarcodeGuide() {
A reliable <strong>Barcode Generator</strong> helps streamline these processes and improves efficiency. A reliable <strong>Barcode Generator</strong> helps streamline these processes and improves efficiency.
</p> </p>
<h3>Understanding Check Digits</h3> <h2>Understanding Check Digits</h2>
<p> <p>
Most barcodes (like EAN and UPC) include a "Check Digit"the last number in the sequence. This digit is calculated mathematically from the other numbers to ensure the barcode is scanned correctly. Even if a barcode is slightly damaged or scratched, the scanner uses the check digit to verify the integrity of the data. Most barcodes (like EAN and UPC) include a "Check Digit"the last number in the sequence. This digit is calculated mathematically from the other numbers to ensure the barcode is scanned correctly. Even if a barcode is slightly damaged or scratched, the scanner uses the check digit to verify the integrity of the data.
</p> </p>
<h3>Best Practices for Printing Barcodes</h3> <h2>Best Practices for Printing Barcodes</h2>
<p> <p>
To ensure your barcodes scan instantly at the checkout or in the warehouse, follow these printing tips: To ensure your barcodes scan instantly at the checkout or in the warehouse, follow these printing tips:
</p> </p>
@ -264,7 +266,7 @@ export function BarcodeGuide() {
<div className="flex items-center gap-3 mb-6 not-prose"> <div className="flex items-center gap-3 mb-6 not-prose">
<HelpCircle className="w-6 h-6 text-blue-500" /> <HelpCircle className="w-6 h-6 text-blue-500" />
<h3 className="text-2xl font-bold text-slate-900 m-0">Frequently Asked Questions (FAQ)</h3> <h2 className="text-2xl font-bold text-slate-900 m-0">Frequently Asked Questions (FAQ)</h2>
</div> </div>
<div className="not-prose space-y-8"> <div className="not-prose space-y-8">

View File

@ -8,7 +8,7 @@ const INDEXNOW_ENDPOINT = 'https://api.indexnow.org/indexnow';
const HOST = 'www.qrmaster.net'; const HOST = 'www.qrmaster.net';
// You need to generate a key from https://www.bing.com/indexnow and place it in your public folder // You need to generate a key from https://www.bing.com/indexnow and place it in your public folder
// For now, we'll assume a key exists or is provided via env // For now, we'll assume a key exists or is provided via env
const KEY = process.env.INDEXNOW_KEY || 'your-indexnow-key'; const KEY = process.env.INDEXNOW_KEY || 'bb6dfaacf1ed41a880281c426c54ed7c';
const KEY_LOCATION = `https://${HOST}/${KEY}.txt`; const KEY_LOCATION = `https://${HOST}/${KEY}.txt`;
export async function submitToIndexNow(urls: string[]) { export async function submitToIndexNow(urls: string[]) {