diff --git a/linear.app/DESIGN.md b/linear.app/DESIGN.md new file mode 100644 index 0000000..1589d6d --- /dev/null +++ b/linear.app/DESIGN.md @@ -0,0 +1,548 @@ +--- +version: alpha +name: Linear +description: "A near-black product-focused marketing canvas built around #010102 (the deepest dark surface of any tool in this collection), light gray text (#f7f8f8), and the signature Linear lavender-blue (#5e6ad2) used as the single chromatic accent. The system reads as software-craft documentation: dense, technical, and quietly luxurious. Display type is set in the Linear custom sans (SF Pro Display fallback) at 500–700 with measured negative tracking. Cards live as charcoal panels (#0f1011) with hairline borders. The accent lavender appears on the brand mark, focus rings, and a few intentional CTAs — never decoratively. Page rhythm leans on product UI screenshots framed in dark panels rather than atmospheric color." + +colors: + primary: "#5e6ad2" + on-primary: "#ffffff" + primary-hover: "#828fff" + primary-focus: "#5e69d1" + ink: "#f7f8f8" + ink-muted: "#d0d6e0" + ink-subtle: "#8a8f98" + ink-tertiary: "#62666d" + canvas: "#010102" + surface-1: "#0f1011" + surface-2: "#141516" + surface-3: "#18191a" + surface-4: "#191a1b" + hairline: "#23252a" + hairline-strong: "#34343a" + hairline-tertiary: "#3e3e44" + inverse-canvas: "#ffffff" + inverse-surface-1: "#f5f6f6" + inverse-surface-2: "#f6f7f7" + inverse-ink: "#000000" + brand-secure: "#7a7fad" + semantic-success: "#27a644" + semantic-overlay: "#000000" + +typography: + display-xl: + fontFamily: Linear Display + fontSize: 80px + fontWeight: 600 + lineHeight: 1.05 + letterSpacing: -3.0px + display-lg: + fontFamily: Linear Display + fontSize: 56px + fontWeight: 600 + lineHeight: 1.10 + letterSpacing: -1.8px + display-md: + fontFamily: Linear Display + fontSize: 40px + fontWeight: 600 + lineHeight: 1.15 + letterSpacing: -1.0px + headline: + fontFamily: Linear Display + fontSize: 28px + fontWeight: 600 + lineHeight: 1.20 + letterSpacing: -0.6px + card-title: + fontFamily: Linear Display + fontSize: 22px + fontWeight: 500 + lineHeight: 1.25 + letterSpacing: -0.4px + subhead: + fontFamily: Linear Display + fontSize: 20px + fontWeight: 400 + lineHeight: 1.40 + letterSpacing: -0.2px + body-lg: + fontFamily: Linear Text + fontSize: 18px + fontWeight: 400 + lineHeight: 1.50 + letterSpacing: -0.1px + body: + fontFamily: Linear Text + fontSize: 16px + fontWeight: 400 + lineHeight: 1.50 + letterSpacing: -0.05px + body-sm: + fontFamily: Linear Text + fontSize: 14px + fontWeight: 400 + lineHeight: 1.50 + letterSpacing: 0 + caption: + fontFamily: Linear Text + fontSize: 12px + fontWeight: 400 + lineHeight: 1.40 + letterSpacing: 0 + button: + fontFamily: Linear Text + fontSize: 14px + fontWeight: 500 + lineHeight: 1.20 + letterSpacing: 0 + eyebrow: + fontFamily: Linear Text + fontSize: 13px + fontWeight: 500 + lineHeight: 1.30 + letterSpacing: 0.4px + mono: + fontFamily: Linear Mono + fontSize: 13px + fontWeight: 400 + lineHeight: 1.50 + letterSpacing: 0 + +rounded: + xs: 4px + sm: 6px + md: 8px + lg: 12px + xl: 16px + xxl: 24px + pill: 9999px + full: 9999px + +spacing: + xxs: 4px + xs: 8px + sm: 12px + md: 16px + lg: 24px + xl: 32px + xxl: 48px + section: 96px + +components: + button-primary: + backgroundColor: "{colors.primary}" + textColor: "{colors.on-primary}" + typography: "{typography.button}" + rounded: "{rounded.md}" + padding: 8px 14px + button-primary-pressed: + backgroundColor: "{colors.primary-focus}" + textColor: "{colors.on-primary}" + typography: "{typography.button}" + rounded: "{rounded.md}" + button-primary-hover: + backgroundColor: "{colors.primary-hover}" + textColor: "{colors.on-primary}" + typography: "{typography.button}" + rounded: "{rounded.md}" + button-secondary: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.button}" + rounded: "{rounded.md}" + padding: 8px 14px + button-tertiary: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.button}" + rounded: "{rounded.md}" + padding: 8px 14px + button-inverse: + backgroundColor: "{colors.inverse-canvas}" + textColor: "{colors.inverse-ink}" + typography: "{typography.button}" + rounded: "{rounded.md}" + padding: 8px 14px + pricing-card: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.body}" + rounded: "{rounded.lg}" + padding: 24px + pricing-card-featured: + backgroundColor: "{colors.surface-2}" + textColor: "{colors.ink}" + typography: "{typography.body}" + rounded: "{rounded.lg}" + padding: 24px + feature-card: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.body}" + rounded: "{rounded.lg}" + padding: 24px + product-screenshot-card: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.body}" + rounded: "{rounded.xl}" + padding: 24px + testimonial-card: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.body-lg}" + rounded: "{rounded.lg}" + padding: 32px + customer-logo-tile: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink-subtle}" + typography: "{typography.caption}" + rounded: "{rounded.xs}" + padding: 16px + text-input: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.body}" + rounded: "{rounded.md}" + padding: 8px 12px + text-input-focused: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.body}" + rounded: "{rounded.md}" + padding: 8px 12px + pricing-tab-default: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink-subtle}" + typography: "{typography.button}" + rounded: "{rounded.pill}" + padding: 6px 14px + pricing-tab-selected: + backgroundColor: "{colors.surface-2}" + textColor: "{colors.ink}" + typography: "{typography.button}" + rounded: "{rounded.pill}" + padding: 6px 14px + cta-banner: + backgroundColor: "{colors.surface-1}" + textColor: "{colors.ink}" + typography: "{typography.headline}" + rounded: "{rounded.lg}" + padding: 48px + changelog-row: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body}" + rounded: "{rounded.xs}" + padding: 24px 0 + status-badge: + backgroundColor: "{colors.surface-2}" + textColor: "{colors.ink-muted}" + typography: "{typography.caption}" + rounded: "{rounded.pill}" + padding: 2px 8px + top-nav: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink}" + typography: "{typography.body-sm}" + rounded: "{rounded.xs}" + height: 56px + footer: + backgroundColor: "{colors.canvas}" + textColor: "{colors.ink-subtle}" + typography: "{typography.caption}" + rounded: "{rounded.xs}" + padding: 64px 32px +--- + +## Overview + +Linear's marketing canvas is the deepest dark surface in this collection — `{colors.canvas}` is #010102, essentially pure black with a faint blue tint. On top sits a four-step surface ladder (`{colors.surface-1}` through `{colors.surface-4}`) for cards, panels, and lifted tiles, with hairline borders running from `{colors.hairline}` (#23252a) up through `{colors.hairline-strong}` and `{colors.hairline-tertiary}`. Light gray text (`{colors.ink}` #f7f8f8) carries the body and headlines. + +The single chromatic accent is **Linear lavender-blue** `{colors.primary}` (#5e6ad2) — used on the brand mark, focus rings, and the primary CTA button. A lighter hover state (`{colors.primary-hover}` #828fff) and a focus-tinted variant (`{colors.primary-focus}` #5e69d1) extend the same hue. Linear avoids saturated greens, oranges, reds, etc. on the marketing canvas — the only semantic color is `{colors.semantic-success}` (#27a644) for status pills and the rare success indicator. + +Display type runs Linear's custom sans (with `SF Pro Display` fallback) at weight 500–700 with negative letter-spacing scaling from -3.0px at 80px down to 0 at body. The body family is Linear's text cut, and a Linear Mono is reserved for code snippets in product screenshots. + +The page rhythm is **dense product screenshots** — Linear's marketing leads with high-fidelity captures of the product UI (issue list, project view, dashboard) framed in `{colors.surface-1}` panels with `{rounded.xl}` 16px corners. The chrome is intentionally minimal so the app screenshots can do the heavy lifting. + +**Key Characteristics:** +- **Dark-canvas marketing system** — `{colors.canvas}` (#010102) is the deepest dark in this collection. +- **Lavender-blue brand accent** (`{colors.primary}` #5e6ad2) — used scarcely on brand mark, focus, and the primary CTA. +- Four-step surface ladder (canvas → surface-1 → surface-2 → surface-3 → surface-4) carries hierarchy without shadow. +- Display tracking pulls aggressively negative (-3.0px at 80px); body holds at -0.05px. +- Cards use `{rounded.lg}` 12px corners with 1px hairline borders — never pill, rarely 16px. +- **Product UI screenshots** dominate the page. The marketing chrome is a dark frame for the app. +- No second chromatic color. No atmospheric gradients. No spotlight cards. + +## Colors + +> Source pages: linear.app (home), /intake, /pricing, /contact/sales, /build. + +### Brand & Accent +- **Lavender-Blue** ({colors.primary}): The signature Linear accent — primary CTA, brand mark, link emphasis. +- **Lavender Hover** ({colors.primary-hover}): Lighter lavender (#828fff) — hovered state of the primary CTA. +- **Lavender Focus** ({colors.primary-focus}): Focus-ring tint (#5e69d1) — focused inputs, focused buttons. +- **Brand Secure** ({colors.brand-secure}): Muted lavender-gray (#7a7fad) — used in "Linear Security" surfaces. + +### Surface +- **Canvas** ({colors.canvas}): Default page background — #010102, near-pure black with a faint blue tint. +- **Surface 1** ({colors.surface-1}): One step above canvas — feature cards, pricing cards, product screenshot panels. +- **Surface 2** ({colors.surface-2}): Two steps above — featured pricing card, hovered cards. +- **Surface 3** ({colors.surface-3}): Three steps above — line-tertiary backgrounds, sub-nav. +- **Surface 4** ({colors.surface-4}): Four steps above — bg-level-3, deepest lifted surface. +- **Hairline** ({colors.hairline}): 1px borders on cards and dividers. +- **Hairline Strong** ({colors.hairline-strong}): Stronger 1px borders — input focus rings. +- **Hairline Tertiary** ({colors.hairline-tertiary}): Tertiary borders for nested surfaces. +- **Inverse Canvas** ({colors.inverse-canvas}): Pure white — surface of the inverse pill CTA on a small set of section openers. +- **Inverse Surface 1** ({colors.inverse-surface-1}): One step above inverse canvas. +- **Inverse Surface 2** ({colors.inverse-surface-2}): Two steps above inverse canvas. + +### Text +- **Ink** ({colors.ink}): All headlines and emphasized body type — light gray #f7f8f8. +- **Ink Muted** ({colors.ink-muted}): Secondary type at #d0d6e0 — meta info on hero panels. +- **Ink Subtle** ({colors.ink-subtle}): Tertiary type at #8a8f98 — deselected pricing tabs, footer columns. +- **Ink Tertiary** ({colors.ink-tertiary}): Quaternary at #62666d — disabled, footnotes. + +### Semantic +- **Success Green** ({colors.semantic-success}): Status pills, success indicators. The only semantic color on marketing. +- **Overlay** ({colors.semantic-overlay}): Pure black overlay scrim for modals. + +## Typography + +### Font Family + +- **Linear Display** — Linear's custom display sans; fallback `SF Pro Display, -apple-system, system-ui, Segoe UI, Roboto`. Carries display-xl through subhead. +- **Linear Text** — Linear's custom text sans (a slightly different cut tuned for body sizes); same fallback stack. Carries body sizes, button labels, captions. +- **Linear Mono** — Linear's custom mono; fallback `ui-monospace, SF Mono, Menlo`. Used for code snippets in product screenshots and for status / ID tokens. + +The marketing surface treats Display and Text as one continuous voice; the family change is silent. + +### Hierarchy + +| Token | Size | Weight | Line Height | Letter Spacing | Use | +|---|---|---|---|---|---| +| `{typography.display-xl}` | 80px | 600 | 1.05 | -3.0px | Largest hero headline | +| `{typography.display-lg}` | 56px | 600 | 1.10 | -1.8px | Section opener headlines | +| `{typography.display-md}` | 40px | 600 | 1.15 | -1.0px | Sub-section headlines | +| `{typography.headline}` | 28px | 600 | 1.20 | -0.6px | Pricing tier titles, CTA banner heading | +| `{typography.card-title}` | 22px | 500 | 1.25 | -0.4px | Feature card title | +| `{typography.subhead}` | 20px | 400 | 1.40 | -0.2px | Lead body, intro paragraphs | +| `{typography.body-lg}` | 18px | 400 | 1.50 | -0.1px | Hero subhead, lead paragraphs | +| `{typography.body}` | 16px | 400 | 1.50 | -0.05px | Default body | +| `{typography.body-sm}` | 14px | 400 | 1.50 | 0 | Card body, footer columns | +| `{typography.caption}` | 12px | 400 | 1.40 | 0 | Captions, meta, status | +| `{typography.button}` | 14px | 500 | 1.20 | 0 | All button labels | +| `{typography.eyebrow}` | 13px | 500 | 1.30 | 0.4px | Section eyebrow (slight positive tracking) | +| `{typography.mono}` | 13px | 400 | 1.50 | 0 | Linear Mono for code in product screenshots | + +### Principles + +- **Aggressive negative tracking on display** (-3.0px at 80px ≈ 4% of size). +- **Single voice from display to body.** Display-xl at 600 → body at 400 — same family, narrower weights. +- **Eyebrow uses positive tracking** (+0.4px) — contrast against the negative-tracked display marks the eyebrow as taxonomy. +- **Mono only in code contexts.** Linear Mono lives inside product screenshots — not on marketing chrome. + +### Note on Font Substitutes + +Linear's custom typeface isn't publicly distributed; the documented fallback `SF Pro Display, -apple-system, system-ui` is the recommended substitute on macOS. For cross-platform implementation, **Inter** at weight 500 / 600 / 700 is the closest free substitute. **Geist Sans** is also viable. For mono, **JetBrains Mono** or **Geist Mono** at weight 400 closely approximates Linear Mono. + +## Layout + +### Spacing System + +- **Base unit**: 4px. +- **Tokens (front matter)**: `{spacing.xxs}` 4px · `{spacing.xs}` 8px · `{spacing.sm}` 12px · `{spacing.md}` 16px · `{spacing.lg}` 24px · `{spacing.xl}` 32px · `{spacing.xxl}` 48px · `{spacing.section}` 96px. +- Card interior padding: `{spacing.lg}` 24px on feature/pricing cards; `{spacing.xl}` 32px on testimonial cards; `{spacing.xxl}` 48px on CTA banners. +- Pill button padding: 8px vertical · 14px horizontal — Linear's compact button spec. +- Form input padding: 8px vertical · 12px horizontal. + +### Grid & Container + +- Max content width sits around 1280px. +- Card grids are 3-up at desktop, 2-up at tablet, 1-up at mobile. +- Pricing tier grid is 3-up; comparison strip below shows checkmarks per tier. +- Product screenshot panels span full content width — they're the protagonist. + +### Whitespace Philosophy + +The dark canvas IS the whitespace. Sections separate by lift onto surface-1 panels, not by gaps in white. Within a panel, generous `{spacing.lg}` 24px gaps between content blocks; `{spacing.section}` 96px between sections. + +## Elevation & Depth + +| Level | Treatment | Use | +|---|---|---| +| 0 (flat) | No shadow, no border | Default for body type, hero text, footer | +| 1 (charcoal lift) | `{colors.surface-1}` background on canvas, 1px `{colors.hairline}` | Default cards, product panels | +| 2 (surface-2 lift) | `{colors.surface-2}` background, 1px `{colors.hairline-strong}` | Featured pricing card, hovered cards | +| 3 (surface-3 lift) | `{colors.surface-3}` background | Sub-nav, dropdown menus | +| 4 (focus ring) | 2px `{colors.primary-focus}` outline at 50% opacity | Focused input, focused button | + +Linear's depth is carried by surface ladder + hairline borders. The brand resists drop shadows on dark almost entirely. + +### Decorative Depth + +- **Product UI screenshots** dominate as decorative depth. +- **No atmospheric gradients, no spotlight cards.** +- **Subtle white edge highlight** on the top edge of lifted panels — gives the dark surface a faint "pixel rendered" feel. + +## Shapes + +### Border Radius Scale + +| Token | Value | Use | +|---|---|---| +| `{rounded.xs}` | 4px | Small chips, status badges | +| `{rounded.sm}` | 6px | Inline tags | +| `{rounded.md}` | 8px | All buttons, form inputs | +| `{rounded.lg}` | 12px | Pricing cards, feature cards, testimonial cards | +| `{rounded.xl}` | 16px | Product screenshot panels | +| `{rounded.xxl}` | 24px | Oversized CTA banners (rare) | +| `{rounded.pill}` | 9999px | Pricing tab toggles, status pills | +| `{rounded.full}` | 9999px | Avatar circles | + +### Photography & Illustration Geometry + +- Product UI screenshots dominate; they sit in `{rounded.xl}` 16px tiles with `{spacing.lg}` 24px outer padding. +- Customer logo tiles render at small sizes (~24px logo height) on `{colors.canvas}` with no border. +- Avatar circles in testimonial cards use `{rounded.full}` at 32–40px sizes. + +## Components + +### Buttons + +**`button-primary`** — Lavender CTA. The default primary CTA across all pages. +- Background `{colors.primary}`, text `{colors.on-primary}`, type `{typography.button}`, padding 8px 14px, rounded `{rounded.md}`. +- Pressed state lives in `button-primary-pressed` (background shifts to `{colors.primary-focus}`). +- Hover state lives in `button-primary-hover` (background shifts to `{colors.primary-hover}` lighter lavender). + +**`button-secondary`** — Charcoal button. Used for secondary CTAs ("Sign in", "Read changelog"). +- Background `{colors.surface-1}`, text `{colors.ink}`, type `{typography.button}`, padding 8px 14px, rounded `{rounded.md}`. 1px `{colors.hairline}` border. + +**`button-tertiary`** — Plain text button. +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.button}`, rounded `{rounded.md}`, padding 8px 14px. + +**`button-inverse`** — White-on-dark inverse CTA. +- Background `{colors.inverse-canvas}`, text `{colors.inverse-ink}`, type `{typography.button}`, rounded `{rounded.md}`, padding 8px 14px. + +### Pricing Tabs + +**`pricing-tab-default`** + **`pricing-tab-selected`** — Pill-toggle on `/pricing`. +- Default: `{colors.canvas}` background, `{colors.ink-subtle}` text, rounded `{rounded.pill}`, padding 6px 14px. +- Selected: `{colors.surface-2}` background, `{colors.ink}` text — selected = surface lift. + +### Cards & Containers + +**`pricing-card`** — Each tier on `/pricing`. +- Background `{colors.surface-1}`, text `{colors.ink}`, type `{typography.body}`, rounded `{rounded.lg}`, padding 24px. 1px `{colors.hairline}` border. + +**`pricing-card-featured`** — Recommended tier — surface lift to surface-2. +- Background `{colors.surface-2}`, otherwise identical structure. + +**`feature-card`** — Generic feature highlight tile. +- Background `{colors.surface-1}`, text `{colors.ink}`, type `{typography.body}`, rounded `{rounded.lg}`, padding 24px. + +**`product-screenshot-card`** — The dominant card type — frames a high-fidelity Linear app UI screenshot. +- Background `{colors.surface-1}`, text `{colors.ink}`, type `{typography.body}`, rounded `{rounded.xl}`, padding 24px. + +**`testimonial-card`** — Customer quote with avatar + name + role. +- Background `{colors.surface-1}`, text `{colors.ink}`, type `{typography.body-lg}`, rounded `{rounded.lg}`, padding 32px. + +**`customer-logo-tile`** — Small tile in the customer marquee. +- Background `{colors.canvas}`, text `{colors.ink-subtle}`, type `{typography.caption}`, rounded `{rounded.xs}`, padding 16px. + +**`cta-banner`** — Closing CTA panel near page bottom. +- Background `{colors.surface-1}`, text `{colors.ink}`, type `{typography.headline}`, rounded `{rounded.lg}`, padding 48px. + +### Inputs & Forms + +**`text-input`** + **`text-input-focused`** — Form fields on `/contact/sales` and signup overlays. +- Background `{colors.surface-1}`, text `{colors.ink}`, type `{typography.body}`, rounded `{rounded.md}`, padding 8px 12px. +- Focused state retains the same surface; the focus ring is a 2px `{colors.primary-focus}` outline at 50% opacity. + +### Status & Build Page + +**`changelog-row`** — Each row in `/build` (changelog page) listing version, date, and changes. +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.body}`, rounded `{rounded.xs}`, padding 24px 0. 1px `{colors.hairline}` bottom rule. + +**`status-badge`** — Small status pill. +- Background `{colors.surface-2}`, text `{colors.ink-muted}`, type `{typography.caption}`, rounded `{rounded.pill}`, padding 2px 8px. + +### Navigation + +**`top-nav`** — Sticky dark bar with the Linear wordmark left, primary nav links centered, and a `button-secondary` ("Sign in") + `button-primary` ("Get started") pair right. +- Background `{colors.canvas}`, text `{colors.ink}`, type `{typography.body-sm}`, height 56px. + +### Footer + +**`footer`** — Dense link grid on `{colors.canvas}` with the Linear wordmark left. +- Background `{colors.canvas}`, text `{colors.ink-subtle}`, type `{typography.caption}`, padding 64px 32px. + +## Do's and Don'ts + +### Do + +- Reserve `{colors.canvas}` (#010102) as the system's anchor surface — the faint blue tint is intentional. +- Use `{colors.primary}` lavender ONLY for: brand mark, primary CTA, focus ring, link emphasis. +- Use the four-step surface ladder for hierarchy. Avoid skipping levels. +- Pair display weight 600 with body weight 400 — Linear resists 700+ display weights. +- Apply negative letter-spacing aggressively on display. +- Use product UI screenshots as the protagonist of every section. +- Compose CTAs as `{rounded.md}` 8px corners. + +### Don't + +- Don't ship a light-mode marketing page. +- Don't use lavender as a section background or card fill. +- Don't introduce a second chromatic accent (orange, pink, green for marketing). +- Don't add atmospheric gradients or spotlight cards. +- Don't pill-round CTAs. +- Don't use `#000000` true black as the canvas. +- Don't combine multiple bright accents in product screenshot mockups. + +## Responsive Behavior + +### Breakpoints + +| Name | Width | Key Changes | +|---|---|---| +| Desktop-XL | 1440px | Default desktop layout | +| Desktop | 1280px | Card grid 3-up maintained | +| Tablet | 1024px | Card grid 3-up → 2-up | +| Mobile-Lg | 768px | Pricing comparison becomes accordion; nav hamburger | +| Mobile | 480px | Single-column; display-xl scales 80px → ~36px | + +### Touch Targets + +- CTAs hold ≥40px tap height across viewports. +- Pricing tab pills hold ≥36px tap height; touch viewports grow to ≥44px. +- Form inputs hold ≥44px tap target on touch. + +### Collapsing Strategy + +- **Top nav**: links collapse to hamburger below 768px. +- **Card grids**: 3-up → 2-up at 1024px → 1-up below 768px. +- **Pricing comparison**: per-tier accordion below 768px. +- **Display type**: `{typography.display-xl}` 80px scales toward `{typography.display-md}` 40px on mobile. + +### Image Behavior + +- Product UI screenshots maintain aspect ratio and never crop. +- Customer logos in the marquee may collapse from 6-up to 3-up below 768px. + +## Iteration Guide + +1. Focus on ONE component at a time and reference it by its `components:` token name. +2. When introducing a section, decide first which surface lift it lives on. +3. Default body to `{typography.body}` at weight 400. +4. Run `npx @google/design.md lint DESIGN.md` after edits. +5. Add new variants as separate component entries. +6. Treat lavender as scarce: brand mark, primary CTA, focus, link emphasis. +7. Lead every section with a product UI screenshot. + +## Known Gaps + +- The four-step surface ladder values are extracted directly from Linear's `--color-bg-level-3`, `--color-line-tint`, etc. CSS variables; they are Linear's canonical surface spec. +- Form-field error and validation styling is not visible on the inspected pages. +- Light mode is not documented because the marketing site does not ship a light theme. +- Linear's actual product UI uses a richer color-tag palette (red, orange, yellow, green, blue, purple) for issue priorities and project labels — those colors live in the in-product surfaces shown in mockups. +- The custom display, text, and mono families are proprietary; an open-source substitute is acceptable. diff --git a/memory/upgrade_nudge_status.md b/memory/upgrade_nudge_status.md new file mode 100644 index 0000000..4a3c30c --- /dev/null +++ b/memory/upgrade_nudge_status.md @@ -0,0 +1,41 @@ +# Upgrade Nudge Status Memory + +Last updated: 2026-05-02 + +Purpose: local memory for upgrade-nudge outreach status when SMTP/Sent-folder evidence is incomplete. `sent_assumed_manual` means the user instructed us to treat the contact as already sent for future filtering, not that a verifiable SMTP/Sent record was found. + +## Pending send + +These are the two highest-priority upgrade candidates. Do not mark as sent until the upgrade email is actually sent. + +| Name | Email | Stage | Lead score | Reason | +| --- | --- | --- | ---: | --- | +| Ishemupenyu Chagonda | info@aldenadvisory.co.uk | Upgrade Candidate | 105 | User confirmed no upgrade email has been sent yet | +| Shreya Hegde | shhegde@linkedin.com | Upgrade Candidate | 95 | User confirmed no upgrade email has been sent yet | + +## Marked as sent by manual memory + +These contacts should be treated as already sent when filtering future upgrade-nudge batches. + +| Name | Email | Stage | Lead score | Status | +| --- | --- | --- | ---: | --- | +| Marcos Pagan | marcos@easternalliancerealty.com | Upgrade Candidate | 80 | sent_assumed_manual | +| katie Loucaides | katie.loucaides@rya.org.uk | Upgrade Candidate | 70 | sent_assumed_manual | +| Lindsey Holtz | lholtz@uwhealth.org | Upgrade Candidate | 70 | sent_assumed_manual | +| Janell Elder | janell.elder@gov.sk.ca | Upgrade Candidate | 70 | sent_assumed_manual | +| Nouf Saud | nouna.1428@gmail.com | Hot | 65 | sent_assumed_manual | +| Richie Shawl | richie.shawl@alfalaval.com | Hot | 60 | sent_assumed_manual | +| Patricia Hartmann | patricia.hartmann@agderfk.no | Hot | 60 | sent_assumed_manual | +| Andreas Knuth | andreas.knuth@gmail.com | Hot | unknown | sent_assumed_manual | + +## Excluded + +| Name | Email | Stage | Reason | +| --- | --- | --- | --- | +| Profoto Malaysia Sdn Bhd | profotomalaysia@gmail.com | Paid | Already PRO/Paid, not an upgrade-nudge target | + +## Notes + +- IMAP `Sent` check on 2026-05-02 found no verifiable Day-7 upgrade-nudge email records. +- The currently configured database lacks the `upgradeNudgeSentAt` column, so app-level sent status could not be verified there. +- Future upgrade-nudge sends should prioritize `info@aldenadvisory.co.uk` and `shhegde@linkedin.com`. diff --git a/src/app/(main)/(marketing)/about/page.tsx b/src/app/(main)/(marketing)/about/page.tsx index 2b3375e..ddf86b4 100644 --- a/src/app/(main)/(marketing)/about/page.tsx +++ b/src/app/(main)/(marketing)/about/page.tsx @@ -8,11 +8,11 @@ import { CheckCircle2, Shield, Users, BarChart3, Globe, Lock } from 'lucide-reac import { ObfuscatedMailto } from '@/components/ui/ObfuscatedMailto'; export const metadata: Metadata = { - title: 'About QR Master | The Team & Mission Behind the Platform', - description: 'QR Master is built for measurable campaigns and secure QR code operations. Learn about our mission, values, and why businesses trust us.', + title: 'About QR Master | Free QR Code Generator for Businesses', + description: 'QR Master helps businesses create, track, and manage QR codes at scale — free dynamic QR codes, real analytics, and no hidden limits. Learn who we are.', openGraph: { - title: 'About QR Master | Dynamic QR Codes & Analytics', - description: 'We help businesses create, manage, and track QR codes at scale. Transparent pricing, privacy-first, and built for reliability.', + title: 'About QR Master | Free Dynamic QR Codes & Analytics', + description: 'Free dynamic QR codes with scan analytics, custom branding, and no reprint headaches. Learn about the team and mission behind QR Master.', url: 'https://www.qrmaster.net/about', type: 'website', images: ['/og-image.png'], @@ -112,11 +112,11 @@ export default function AboutPage() { -
- - - -
+
+ + + +
diff --git a/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx b/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx index 8d341c5..ef28e7a 100644 --- a/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx +++ b/src/app/(main)/(marketing)/dynamic-qr-code-generator/page.tsx @@ -1,831 +1,1441 @@ -import React from 'react'; -import type { Metadata } from 'next'; -import { Button } from '@/components/ui/Button'; -import { Card } from '@/components/ui/Card'; -import SeoJsonLd from '@/components/SeoJsonLd'; -import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs'; -import { breadcrumbSchema } from '@/lib/schema'; -import { FAQSection } from '@/components/aeo/FAQSection'; -import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock'; -import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; -import { MarketingPageTracker, TrackedCtaLink } from '@/components/marketing/MarketingAnalytics'; -import { featuredUseCases } from '@/lib/growth-pages'; - -export const metadata: Metadata = { - title: { - absolute: 'Free Dynamic QR Code Generator – Update After Printing', - }, - description: - 'Create dynamic QR codes that you can edit after printing. Change the destination URL anytime, track scans, and manage all codes in one dashboard. Free to start.', - keywords: - 'dynamic qr code generator, editable qr code, dynamic qr code, qr code tracking, update qr code after printing', - alternates: { - canonical: 'https://www.qrmaster.net/dynamic-qr-code-generator', - languages: { - 'x-default': 'https://www.qrmaster.net/dynamic-qr-code-generator', - en: 'https://www.qrmaster.net/dynamic-qr-code-generator', - }, - }, - openGraph: { - title: 'Free Dynamic QR Code Generator – Update After Printing', - description: - 'Create dynamic QR codes that you can edit after printing. Change the destination URL anytime, track scans, and manage all codes in one dashboard.', - url: 'https://www.qrmaster.net/dynamic-qr-code-generator', - type: 'website', - images: ['/og-image.png'], - }, - twitter: { - title: 'Free Dynamic QR Code Generator – Update After Printing', - description: - 'Create dynamic QR codes that you can edit after printing. Change the destination URL anytime, track scans, and manage all codes in one dashboard.', - }, -}; - -const featureCards = [ - { - title: 'Edit destination after print', - description: - 'Keep the same QR image on flyers, menus, packaging, or cards while the destination URL changes later.', - }, - { - title: 'Review scan context', - description: - 'See scan information in your dashboard, including time, device, and location context.', - }, - { - title: 'Apply brand styling', - description: - 'Use brand colors and logo styling so the QR code fits printed campaigns and product materials.', - }, - { - title: 'Manage active codes', - description: - 'Keep active dynamic QR codes in one dashboard instead of tracking versions across design files.', - }, - { - title: 'Use one print asset longer', - description: - 'Dynamic QR is useful when the printed surface should stay stable even as the linked page changes.', - }, - { - title: 'Scale by plan', - description: - 'The Free plan includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500.', - }, -]; - -const staticVsDynamic = [ - { - feature: 'Change the destination after print', - static: false, - dynamic: true, - }, - { - feature: 'Review scan analytics later', - static: false, - dynamic: true, - }, - { - feature: 'Keep one print asset across changing campaigns', - static: false, - dynamic: true, - }, - { - feature: 'Manage active codes in a dashboard', - static: false, - dynamic: true, - }, - { - feature: 'Apply brand styling', - static: false, - dynamic: true, - }, -]; - -const useCases = [ - { - title: 'Marketing campaigns', - description: - 'Update campaign landing pages without reprinting flyers, posters, inserts, or signs.', - example: - 'Keep the printed QR live while the destination moves from teaser page to launch page.', - }, - { - title: 'Product packaging', - description: - 'Link packaging to manuals, onboarding pages, or support content and update that destination as stock stays in circulation.', - example: 'Update a software download or setup page without changing the package artwork.', - }, - { - title: 'Business cards', - description: - 'Route contacts to a current landing page, booking page, or profile without printing new cards.', - example: 'Keep the same printed card while your booking or profile destination changes.', - }, - { - title: 'Restaurant menus', - description: - 'Keep table cards useful when menu links, PDFs, or specials need to change after print.', - example: 'Update a menu destination for seasonal specials without replacing every table card.', - }, -]; - -const faqItems = [ - { - question: 'What is a dynamic QR code?', - answer: - 'A dynamic QR code points to a redirect URL, which lets you change the final destination later without replacing the printed QR image.', - }, - { - question: 'Can I change a dynamic QR code after printing?', - answer: - 'Yes. You keep the same QR image and update the destination from your dashboard. The printed code never needs to be replaced.', - }, - { - question: 'How is it different from a static QR code?', - answer: - 'A static QR code stores the destination directly in the code and stays fixed. A dynamic QR code routes through QR Master so the destination can be updated and scans can be reviewed later.', - }, - { - question: 'How many dynamic QR codes can I create?', - answer: - 'The Free plan includes 3 active dynamic QR codes. Pro includes 50 dynamic QR codes, and Business includes 500 dynamic QR codes.', - }, - { - question: 'Is a dynamic QR code free?', - answer: - 'Yes — the Free plan includes 3 active dynamic QR codes at no cost. No credit card required to get started.', - }, - { - question: 'Can I track how many times a dynamic QR code was scanned?', - answer: - 'Yes. Every scan is logged in your dashboard with device type, time, and location context. Pro and Business plans include unlimited scan history.', - }, - { - question: 'How do I convert a static QR code to a dynamic one?', - answer: - 'You cannot convert an existing static QR code — the data is permanently encoded in the image. To switch to dynamic, create a new dynamic QR code in QR Master and replace the printed code.', - }, - { - question: 'What is the best use case for a dynamic QR code?', - answer: - 'Dynamic QR codes are ideal whenever the destination may change after printing: restaurant menus, marketing flyers, product packaging, business cards, and event materials.', - }, -]; - -const servicesComparison = [ - { - service: 'QR Master', - href: 'https://www.qrmaster.net', - freePlan: '3 active dynamic codes (permanent)', - paidFrom: 'EUR 9/month (Pro)', - gdpr: 'Built-in — hashed IPs, all plans', - analytics: 'All plans', - bulk: 'Up to 1,000 codes (Business, EUR 29/mo)', - bestFor: 'SMBs and EU businesses', - highlight: true, - }, - { - service: 'Beaconstac / Uniqode', - href: 'https://www.uniqode.com', - freePlan: 'None', - paidFrom: '$49–99/month (functional tier)', - gdpr: 'Via DPA configuration', - analytics: 'Paid plans', - bulk: 'Enterprise tier only', - bestFor: 'Enterprise (SOC2, SSO, API)', - highlight: false, - }, - { - service: 'QR-Code-Generator.com', - href: 'https://www.qr-code-generator.com', - freePlan: 'Static QR only', - paidFrom: 'From $5/month', - gdpr: 'US company', - analytics: 'Paid plans', - bulk: 'Paid plans', - bestFor: 'Basic, one-off use cases', - highlight: false, - }, - { - service: 'Flowcode', - href: 'https://www.flowcode.com', - freePlan: 'Limited (expires)', - paidFrom: 'From $5/month', - gdpr: 'US company', - analytics: 'Paid plans', - bulk: 'Enterprise only', - bestFor: 'Design-forward branding', - highlight: false, - }, - { - service: 'Canva', - href: 'https://www.canva.com', - freePlan: 'Static only (in designs)', - paidFrom: 'From $15/month (Pro)', - gdpr: 'General policy', - analytics: 'Not included', - bulk: 'Not available', - bestFor: 'Design-first workflows', - highlight: false, - }, -]; - -const servicesItemListSchema = { - '@context': 'https://schema.org', - '@type': 'ItemList', - '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#services', - name: 'Services that offer dynamic QR codes', - description: 'Comparison of QR code platforms that support dynamic (editable) QR codes, analytics, and scan tracking.', - numberOfItems: servicesComparison.length, - itemListElement: servicesComparison.map((s, i) => ({ - '@type': 'ListItem', - position: i + 1, - name: s.service, - url: s.href, - description: `${s.service}: Free plan: ${s.freePlan}. Starting price: ${s.paidFrom}. GDPR: ${s.gdpr}. Best for: ${s.bestFor}.`, - })), -}; - -const softwareSchema = { - '@context': 'https://schema.org', - '@type': 'SoftwareApplication', - '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#software', - name: 'QR Master - Dynamic QR Code Generator', - applicationCategory: 'BusinessApplication', - operatingSystem: 'Web Browser', - offers: { - '@type': 'Offer', - price: '0', - priceCurrency: 'EUR', - availability: 'https://schema.org/InStock', - }, - description: - 'Create dynamic QR codes that can be updated after printing. Change destinations later and review scan context from one dashboard.', - speakable: { - '@type': 'SpeakableSpecification', - cssSelector: ['h1', '.answer-first-block', '.bg-green-50'], - }, - author: { - '@type': 'Person', - name: 'Timo Knuth', - url: 'https://www.qrmaster.net/authors/timo', - }, - dateModified: '2026-04-27', - featureList: [ - 'Edit QR code destinations after printing', - 'Review scan analytics in the dashboard', - 'Apply brand styling with colors and logo', - 'Manage active dynamic QR codes in one place', - 'Scale from 3 active dynamic QR codes on Free to 50 on Pro and 500 on Business', - ], -}; - -const howToSchema = { - '@context': 'https://schema.org', - '@type': 'HowTo', - '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#howto', - name: 'How to create a dynamic QR code', - datePublished: '2024-01-01', - dateModified: '2026-04-27', - author: { - '@type': 'Person', - name: 'Timo Knuth', - url: 'https://www.qrmaster.net/authors/timo', - }, - description: 'Create a dynamic QR code and update the destination later without replacing the printed QR image.', - totalTime: 'PT3M', - step: [ - { - '@type': 'HowToStep', - position: 1, - name: 'Create an account', - text: 'Create a QR Master account and choose a dynamic QR workflow.', - url: 'https://www.qrmaster.net/signup', - }, - { - '@type': 'HowToStep', - position: 2, - name: 'Enter your destination', - text: 'Add the destination URL and style the QR code for print or digital use.', - url: 'https://www.qrmaster.net/signup', - }, - { - '@type': 'HowToStep', - position: 3, - name: 'Download and deploy', - text: 'Download the QR code and place it on printed or digital materials.', - }, - { - '@type': 'HowToStep', - position: 4, - name: 'Update later', - text: 'Change the destination from your dashboard without replacing the QR image.', - }, - ], -}; - -const faqSchema = { - '@context': 'https://schema.org', - '@type': 'FAQPage', - '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#faq', - mainEntity: faqItems.map((item) => ({ - '@type': 'Question', - name: item.question, - acceptedAnswer: { - '@type': 'Answer', - text: item.answer, - }, - })), -}; - -const breadcrumbItems: BreadcrumbItem[] = [ - { name: 'Home', url: '/' }, - { name: 'Dynamic QR Code Generator', url: '/dynamic-qr-code-generator' }, -]; - -const relatedUseCaseLinks = [ - { - href: featuredUseCases[0].href, - title: featuredUseCases[0].title, - description: featuredUseCases[0].summary, - ctaLabel: featuredUseCases[0].ctaLabel, - }, - { - href: '/use-cases/payment-qr-codes', - title: 'Payment QR Codes', - description: - 'Use one printed payment prompt that stays useful even when the checkout or provider path changes.', - ctaLabel: 'Create your payment QR code', - }, - { - href: featuredUseCases[1].href, - title: featuredUseCases[1].title, - description: featuredUseCases[1].summary, - ctaLabel: featuredUseCases[1].ctaLabel, - }, - { - href: '/qr-code-tracking', - title: 'Track Every QR Code Scan', - description: - 'See device, time, and location context for every scan. Understand which placements drive real activity.', - ctaLabel: 'Track your QR scans', - }, - { - href: '/reprint-calculator', - title: 'QR Code Reprint Cost Calculator', - description: - 'Calculate how much static QR reprints cost vs one active dynamic QR code.', - ctaLabel: 'Calculate reprint savings', - }, - { - href: '/use-cases', - title: 'Explore the use-case hub', - description: - 'See how dynamic QR workflows connect to commercial pages, tools, and support content.', - ctaLabel: 'Explore QR code use cases', - }, -]; - -export default function DynamicQRCodeGeneratorPage() { - return ( - <> - - -
-
-
- -
-
-
- Edit after printing -
- -
-

- Dynamic QR Code Generator -

-

- Create QR codes you can update after printing. Change the destination later, - review scan context, and keep printed materials useful for longer. -

-
- -
- {[ - 'Change the destination without replacing the printed QR image', - 'Review scan context in one dashboard', - 'Apply logo and brand colors', - 'Scale from 3 active dynamic QR codes on Free to 50 on Pro and 500 on Business', - ].map((feature) => ( -
-
- - - -
- {feature} -
- ))} -
- -
- - - - - - -
-
- -
- -
-
- - {/* Top-left position detection pattern */} - - - - {/* Top-right position detection pattern */} - - - - {/* Bottom-left position detection pattern */} - - - - {/* Data modules */} - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {/* Center logo area */} - - - Q - -
-
-
-
- Current destination - launch.example -
-
- - - -
-
- Updated destination - menu.example -
-
-

- Same QR image, different destination later. -

-
-
- No reprint needed -
-
-
-
-
- -
-

How to Create a Free Dynamic QR Code

- -
- -
- -
- -
-
-
-

Dynamic vs static QR codes

-

- Dynamic QR is the better fit when the destination may change after the printed code is already in use. -

-
- - -
-
-

Feature

- {staticVsDynamic.map((item) => ( -
-

{item.feature}

-
- ))} -
-
-

Static QR

- {staticVsDynamic.map((item) => ( -
- - {item.static ? 'Yes' : 'No'} - -
- ))} -
-
-

Dynamic QR

- {staticVsDynamic.map((item) => ( -
- - {item.dynamic ? 'Yes' : 'No'} - -
- ))} -
-
-
-
-
- -
-
-
-

What you can do with dynamic QR

-

- These are the core product benefits verified by the current QR Master flows and plan limits. -

-
- -
- {featureCards.map((feature) => ( - -

{feature.title}

-

{feature.description}

-
- ))} -
-
-
- -
-
-
-

Where dynamic QR fits best

-

- Use dynamic QR where the destination may evolve after the printed material is already deployed. -

-
- -
- {useCases.map((useCase) => ( - -

{useCase.title}

-

{useCase.description}

-
-

- Example: {useCase.example} -

-
-
- ))} -
-
-
- - {/* WHY DYNAMIC QR — STATISTICS */} -
-
-
- - Research-backed impact -
-

- Why Dynamic QR Codes Deliver Better Business Outcomes -

-

- The ability to update destinations after printing — and track every scan — transforms a static print asset into a measurable marketing channel. -

- -
-
-
89% vs 33%
-

- Companies with strong omnichannel customer engagement — enabled by closed-loop tracking from offline to online — retain 89% of their customers, compared to only 33% for companies with weak omnichannel engagement. -

-

- Source: Aberdeen Group — Omnichannel Customer Engagement Study -

-
- -
-
46%
-

- of small businesses report printing and direct mail errors as a major source of wasted marketing budget. Dynamic QR codes eliminate this risk — update the destination, never reprint. -

-

- Source: Data & Marketing Association (DMA) -

-
-
- -

- By Timo Knuth, QR Master · Last updated: June 2025 · Based on independent academic and industry research -

-
-
- - {/* SERVICES COMPARISON — targets "what services offer dynamic QR codes?" AI query */} -
-
-
- Unbiased comparison -
-

- Which services offer dynamic QR codes? -

-

- Dynamic QR codes — where the destination URL can be changed after printing — are offered by several platforms. Here is how they compare on price, privacy, and use case fit. -

- -
- - - - - - - - - - - - - {servicesComparison.map((row, i) => ( - - - - - - - - - ))} - -
ServiceFree planPaid fromGDPRBulk creationBest for
- {row.highlight ? ( - - {row.service} - This site - - ) : ( - row.service - )} - {row.freePlan}{row.paidFrom}{row.gdpr}{row.bulk}{row.bestFor}
-
- -

- Last updated: April 2026. Pricing may change — verify on each provider's website before purchasing. Beaconstac rebranded to Uniqode in 2023. -

-
-
- - - -
-
-

Start creating dynamic QR codes today

-

- Use one QR code that can keep working even when the destination behind it needs to change. -

-
- - - - - - -
-
-
-
- - ); -} +import React from 'react'; +import type { Metadata } from 'next'; +import { Button } from '@/components/ui/Button'; +import { Card } from '@/components/ui/Card'; +import SeoJsonLd from '@/components/SeoJsonLd'; +import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs'; +import { breadcrumbSchema } from '@/lib/schema'; +import { FAQSection } from '@/components/aeo/FAQSection'; +import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock'; +import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; +import { + MarketingPageTracker, + TrackedCtaLink, +} from '@/components/marketing/MarketingAnalytics'; +import { featuredUseCases } from '@/lib/growth-pages'; + +export const metadata: Metadata = { + title: { + absolute: 'Free Dynamic QR Code Generator - Editable QR Codes', + }, + description: + 'Create a free dynamic QR code generator workflow. Edit QR code destinations after printing, track scans, and manage editable QR codes in one dashboard.', + keywords: + 'dynamic qr code generator, editable qr code, dynamic qr code, qr code tracking, update qr code after printing', + alternates: { + canonical: 'https://www.qrmaster.net/dynamic-qr-code-generator', + languages: { + 'x-default': 'https://www.qrmaster.net/dynamic-qr-code-generator', + en: 'https://www.qrmaster.net/dynamic-qr-code-generator', + }, + }, + openGraph: { + title: 'Free Dynamic QR Code Generator - Editable QR Codes', + description: + 'Create dynamic QR codes that you can edit after printing. Change the destination URL anytime, track scans, and manage all codes in one dashboard.', + url: 'https://www.qrmaster.net/dynamic-qr-code-generator', + type: 'website', + images: ['/og-image.png'], + }, + twitter: { + title: 'Free Dynamic QR Code Generator - Editable QR Codes', + description: + 'Create dynamic QR codes that you can edit after printing. Change the destination URL anytime, track scans, and manage all codes in one dashboard.', + }, +}; + +const featureCards = [ + { + title: 'Edit destination after print', + description: + 'Keep the same QR image on flyers, menus, packaging, or cards while the destination URL changes later.', + }, + { + title: 'Review scan context', + description: + 'See scan information in your dashboard, including time, device, and location context.', + }, + { + title: 'Apply brand styling', + description: + 'Use brand colors and logo styling so the QR code fits printed campaigns and product materials.', + }, + { + title: 'Manage active codes', + description: + 'Keep active dynamic QR codes in one dashboard instead of tracking versions across design files.', + }, + { + title: 'Use one print asset longer', + description: + 'Dynamic QR is useful when the printed surface should stay stable even as the linked page changes.', + }, + { + title: 'Scale by plan', + description: + 'The Free plan includes 3 active dynamic QR codes, Pro includes 50, and Business includes 500.', + }, +]; + +const staticVsDynamic = [ + { + feature: 'Change the destination after print', + static: false, + dynamic: true, + }, + { + feature: 'Review scan analytics later', + static: false, + dynamic: true, + }, + { + feature: 'Keep one print asset across changing campaigns', + static: false, + dynamic: true, + }, + { + feature: 'Manage active codes in a dashboard', + static: false, + dynamic: true, + }, + { + feature: 'Apply brand styling', + static: false, + dynamic: true, + }, +]; + +const useCases = [ + { + title: 'Marketing campaigns', + description: + 'Update campaign landing pages without reprinting flyers, posters, inserts, or signs.', + example: + 'Keep the printed QR live while the destination moves from teaser page to launch page.', + }, + { + title: 'Product packaging', + description: + 'Link packaging to manuals, onboarding pages, or support content and update that destination as stock stays in circulation.', + example: + 'Update a software download or setup page without changing the package artwork.', + }, + { + title: 'Business cards', + description: + 'Route contacts to a current landing page, booking page, or profile without printing new cards.', + example: + 'Keep the same printed card while your booking or profile destination changes.', + }, + { + title: 'Restaurant menus', + description: + 'Keep table cards useful when menu links, PDFs, or specials need to change after print.', + example: + 'Update a menu destination for seasonal specials without replacing every table card.', + }, +]; + +const faqItems = [ + { + question: 'What is a dynamic QR code?', + answer: + 'A dynamic QR code points to a redirect URL, which lets you change the final destination later without replacing the printed QR image.', + }, + { + question: 'Can I change a dynamic QR code after printing?', + answer: + 'Yes. You keep the same QR image and update the destination from your dashboard. The printed code never needs to be replaced.', + }, + { + question: 'How is it different from a static QR code?', + answer: + 'A static QR code stores the destination directly in the code and stays fixed. A dynamic QR code routes through QR Master so the destination can be updated and scans can be reviewed later.', + }, + { + question: 'How many dynamic QR codes can I create?', + answer: + 'The Free plan includes 3 active dynamic QR codes. Pro includes 50 dynamic QR codes, and Business includes 500 dynamic QR codes.', + }, + { + question: 'Is a dynamic QR code free?', + answer: + 'Yes — the Free plan includes 3 active dynamic QR codes at no cost. No credit card required to get started.', + }, + { + question: 'Can I track how many times a dynamic QR code was scanned?', + answer: + 'Yes. Every scan is logged in your dashboard with device type, time, and location context. Pro and Business plans include unlimited scan history.', + }, + { + question: 'How do I convert a static QR code to a dynamic one?', + answer: + 'You cannot convert an existing static QR code — the data is permanently encoded in the image. To switch to dynamic, create a new dynamic QR code in QR Master and replace the printed code.', + }, + { + question: 'What is the best use case for a dynamic QR code?', + answer: + 'Dynamic QR codes are ideal whenever the destination may change after printing: restaurant menus, marketing flyers, product packaging, business cards, and event materials.', + }, +]; + +const servicesComparison = [ + { + service: 'QR Master', + href: 'https://www.qrmaster.net', + freePlan: '3 active dynamic codes (permanent)', + paidFrom: 'EUR 9/month (Pro)', + gdpr: 'Built-in — hashed IPs, all plans', + analytics: 'All plans', + bulk: 'Up to 1,000 codes (Business, EUR 29/mo)', + bestFor: 'SMBs and EU businesses', + highlight: true, + }, + { + service: 'Beaconstac / Uniqode', + href: 'https://www.uniqode.com', + freePlan: 'None', + paidFrom: '$49–99/month (functional tier)', + gdpr: 'Via DPA configuration', + analytics: 'Paid plans', + bulk: 'Enterprise tier only', + bestFor: 'Enterprise (SOC2, SSO, API)', + highlight: false, + }, + { + service: 'QR-Code-Generator.com', + href: 'https://www.qr-code-generator.com', + freePlan: 'Static QR only', + paidFrom: 'From $5/month', + gdpr: 'US company', + analytics: 'Paid plans', + bulk: 'Paid plans', + bestFor: 'Basic, one-off use cases', + highlight: false, + }, + { + service: 'Flowcode', + href: 'https://www.flowcode.com', + freePlan: 'Limited (expires)', + paidFrom: 'From $5/month', + gdpr: 'US company', + analytics: 'Paid plans', + bulk: 'Enterprise only', + bestFor: 'Design-forward branding', + highlight: false, + }, + { + service: 'Canva', + href: 'https://www.canva.com', + freePlan: 'Static only (in designs)', + paidFrom: 'From $15/month (Pro)', + gdpr: 'General policy', + analytics: 'Not included', + bulk: 'Not available', + bestFor: 'Design-first workflows', + highlight: false, + }, +]; + +const servicesItemListSchema = { + '@context': 'https://schema.org', + '@type': 'ItemList', + '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#services', + name: 'Services that offer dynamic QR codes', + description: + 'Comparison of QR code platforms that support dynamic (editable) QR codes, analytics, and scan tracking.', + numberOfItems: servicesComparison.length, + itemListElement: servicesComparison.map((s, i) => ({ + '@type': 'ListItem', + position: i + 1, + name: s.service, + url: s.href, + description: `${s.service}: Free plan: ${s.freePlan}. Starting price: ${s.paidFrom}. GDPR: ${s.gdpr}. Best for: ${s.bestFor}.`, + })), +}; + +const softwareSchema = { + '@context': 'https://schema.org', + '@type': 'SoftwareApplication', + '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#software', + name: 'QR Master - Dynamic QR Code Generator', + applicationCategory: 'BusinessApplication', + operatingSystem: 'Web Browser', + offers: { + '@type': 'Offer', + price: '0', + priceCurrency: 'EUR', + availability: 'https://schema.org/InStock', + }, + description: + 'Create dynamic QR codes that can be updated after printing. Change destinations later and review scan context from one dashboard.', + speakable: { + '@type': 'SpeakableSpecification', + cssSelector: ['h1', '.answer-first-block', '.bg-green-50'], + }, + author: { + '@type': 'Person', + name: 'Timo Knuth', + url: 'https://www.qrmaster.net/authors/timo', + }, + dateModified: '2026-05-10', + featureList: [ + 'Edit QR code destinations after printing', + 'Review scan analytics in the dashboard', + 'Apply brand styling with colors and logo', + 'Manage active dynamic QR codes in one place', + 'Scale from 3 active dynamic QR codes on Free to 50 on Pro and 500 on Business', + ], +}; + +const howToSchema = { + '@context': 'https://schema.org', + '@type': 'HowTo', + '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#howto', + name: 'How to create a dynamic QR code', + datePublished: '2024-01-01', + dateModified: '2026-05-10', + author: { + '@type': 'Person', + name: 'Timo Knuth', + url: 'https://www.qrmaster.net/authors/timo', + }, + description: + 'Create a dynamic QR code and update the destination later without replacing the printed QR image.', + totalTime: 'PT3M', + step: [ + { + '@type': 'HowToStep', + position: 1, + name: 'Create an account', + text: 'Create a QR Master account and choose a dynamic QR workflow.', + url: 'https://www.qrmaster.net/signup', + }, + { + '@type': 'HowToStep', + position: 2, + name: 'Enter your destination', + text: 'Add the destination URL and style the QR code for print or digital use.', + url: 'https://www.qrmaster.net/signup', + }, + { + '@type': 'HowToStep', + position: 3, + name: 'Download and deploy', + text: 'Download the QR code and place it on printed or digital materials.', + }, + { + '@type': 'HowToStep', + position: 4, + name: 'Update later', + text: 'Change the destination from your dashboard without replacing the QR image.', + }, + ], +}; + +const faqSchema = { + '@context': 'https://schema.org', + '@type': 'FAQPage', + '@id': 'https://www.qrmaster.net/dynamic-qr-code-generator#faq', + mainEntity: faqItems.map((item) => ({ + '@type': 'Question', + name: item.question, + acceptedAnswer: { + '@type': 'Answer', + text: item.answer, + }, + })), +}; + +const breadcrumbItems: BreadcrumbItem[] = [ + { name: 'Home', url: '/' }, + { name: 'Dynamic QR Code Generator', url: '/dynamic-qr-code-generator' }, +]; + +const relatedUseCaseLinks = [ + { + href: featuredUseCases[0].href, + title: featuredUseCases[0].title, + description: featuredUseCases[0].summary, + ctaLabel: featuredUseCases[0].ctaLabel, + }, + { + href: '/use-cases/payment-qr-codes', + title: 'Payment QR Codes', + description: + 'Use one printed payment prompt that stays useful even when the checkout or provider path changes.', + ctaLabel: 'Create your payment QR code', + }, + { + href: featuredUseCases[1].href, + title: featuredUseCases[1].title, + description: featuredUseCases[1].summary, + ctaLabel: featuredUseCases[1].ctaLabel, + }, + { + href: '/qr-code-tracking', + title: 'Track Every QR Code Scan', + description: + 'See device, time, and location context for every scan. Understand which placements drive real activity.', + ctaLabel: 'Track your QR scans', + }, + { + href: '/reprint-calculator', + title: 'QR Code Reprint Cost Calculator', + description: + 'Calculate how much static QR reprints cost vs one active dynamic QR code.', + ctaLabel: 'Calculate reprint savings', + }, + { + href: '/use-cases', + title: 'Explore the use-case hub', + description: + 'See how dynamic QR workflows connect to commercial pages, tools, and support content.', + ctaLabel: 'Explore QR code use cases', + }, +]; + +export default function DynamicQRCodeGeneratorPage() { + return ( + <> + + +
+
+
+ +
+
+
+ Edit after printing +
+ +
+

+ Free Dynamic QR Code Generator +

+

+ Create editable QR codes you can update after printing. + Change the destination later, track scans, and keep flyers, + menus, packaging, and business cards useful for longer. +

+
+ +
+ {[ + 'Change the destination without replacing the printed QR image', + 'Review scan context in one dashboard', + 'Apply logo and brand colors', + 'Scale from 3 active dynamic QR codes on Free to 50 on Pro and 500 on Business', + ].map((feature) => ( +
+
+ + + +
+ {feature} +
+ ))} +
+ +
+ + + + + + +
+
+ +
+ +
+
+ + {/* Top-left position detection pattern */} + + + + {/* Top-right position detection pattern */} + + + + {/* Bottom-left position detection pattern */} + + + + {/* Data modules */} + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {/* Center logo area */} + + + + Q + + +
+
+
+
+ Current destination + + launch.example + +
+
+ + + +
+
+ Updated destination + + menu.example + +
+
+

+ Same QR image, different destination later. +

+
+
+ No reprint needed +
+
+
+
+
+ +
+

+ How to Create a Free Dynamic QR Code +

+ +
+ +
+
+
+

+ Editable QR code workflow +

+

+ What makes a dynamic QR code generator different? +

+

+ A static QR code locks the final URL into the image. A dynamic + QR code generator creates a short managed link first, so QR + Master can redirect scanners to the current destination, record + scan analytics, and let you edit the destination later. +

+
+ +
+ +

+ Editable after print +

+

+ Update campaign URLs, menu PDFs, support pages, or booking + links from the dashboard while the same printed QR code keeps + working. +

+
+ +

+ Track QR code scans +

+

+ Review scan time, device, and location context so offline + materials become measurable instead of invisible. +

+
+ +

+ Built for campaigns +

+

+ Use one editable QR code across flyers, signs, packaging, + event badges, or business cards when the destination may + change. +

+
+
+
+
+ +
+ +
+ +
+
+
+

+ Dynamic vs static QR codes +

+

+ Dynamic QR is the better fit when the destination may change + after the printed code is already in use. +

+
+ + +
+
+

Feature

+ {staticVsDynamic.map((item) => ( +
+

+ {item.feature} +

+
+ ))} +
+
+

+ Static QR +

+ {staticVsDynamic.map((item) => ( +
+ + {item.static ? 'Yes' : 'No'} + +
+ ))} +
+
+

+ Dynamic QR +

+ {staticVsDynamic.map((item) => ( +
+ + {item.dynamic ? 'Yes' : 'No'} + +
+ ))} +
+
+
+
+
+ +
+
+
+

+ What you can do with dynamic QR +

+

+ These are the core product benefits verified by the current QR + Master flows and plan limits. +

+
+ +
+ {featureCards.map((feature) => ( + +

+ {feature.title} +

+

{feature.description}

+
+ ))} +
+
+
+ +
+
+
+

+ Where dynamic QR fits best +

+

+ Use dynamic QR where the destination may evolve after the + printed material is already deployed. +

+
+ +
+ {useCases.map((useCase) => ( + +

+ {useCase.title} +

+

{useCase.description}

+
+

+ Example: {useCase.example} +

+
+
+ ))} +
+
+
+ + {/* WHY DYNAMIC QR — STATISTICS */} +
+
+
+ + + + + Research-backed impact + +
+

+ Why Dynamic QR Codes Deliver Better Business Outcomes +

+

+ The ability to update destinations after printing — and track + every scan — transforms a static print asset into a measurable + marketing channel. +

+ +
+
+
+ 89% vs 33% +
+

+ Companies with strong omnichannel customer engagement — + enabled by closed-loop tracking from offline to online — + retain 89% of their customers, compared to + only 33% for companies with weak omnichannel engagement. +

+

+ Source:{' '} + + Aberdeen Group + {' '} + — Omnichannel Customer Engagement Study +

+
+ +
+
+ 46% +
+

+ of small businesses report printing and direct mail errors as + a major source of wasted marketing budget. Dynamic QR codes + eliminate this risk — update the destination, never reprint. +

+

+ Source:{' '} + + Data & Marketing Association (DMA) + +

+
+
+ +

+ By Timo Knuth, QR Master - Last updated: May 2026 - Based on + independent academic and industry research +

+
+
+ + {/* SERVICES COMPARISON — targets "what services offer dynamic QR codes?" AI query */} +
+
+
+ + Unbiased comparison + +
+

+ Which services offer dynamic QR codes? +

+

+ Dynamic QR codes — where the destination URL can be changed after + printing — are offered by several platforms. Here is how they + compare on price, privacy, and use case fit. +

+ +
+ + + + + + + + + + + + + {servicesComparison.map((row, i) => ( + + + + + + + + + ))} + +
+ Service + + Free plan + + Paid from + + GDPR + + Bulk creation + + Best for +
+ {row.highlight ? ( + + {row.service} + + This site + + + ) : ( + row.service + )} + + {row.freePlan} + + {row.paidFrom} + {row.gdpr}{row.bulk}{row.bestFor}
+
+ +

+ Last updated: May 2026. Pricing may change - verify on each + provider's website before purchasing. Beaconstac rebranded to + Uniqode in 2023. +

+
+
+ + + +
+
+

+ Start creating dynamic QR codes today +

+

+ Use one QR code that can keep working even when the destination + behind it needs to change. +

+
+ + + + + + +
+
+
+
+ + ); +} diff --git a/src/app/(main)/(marketing)/faq/page.tsx b/src/app/(main)/(marketing)/faq/page.tsx index 0e9d77b..3abb1ae 100644 --- a/src/app/(main)/(marketing)/faq/page.tsx +++ b/src/app/(main)/(marketing)/faq/page.tsx @@ -14,9 +14,9 @@ function truncateAtWord(text: string, maxLength: number): string { } export async function generateMetadata(): Promise { - const title = truncateAtWord('QR Code FAQ: Do QR Codes Expire, Work Through Laminate, and More', 60); + const title = truncateAtWord('QR Code FAQ: Expiry, Laminate Scanning & Dynamic QR Explained', 60); const description = truncateAtWord( - 'Answers to common QR code questions: do QR codes expire, will they become obsolete, do they work through laminate, and product-specific questions about dynamic QR codes and tracking.', + 'Quick answers: do QR codes expire? Do they work through laminate? What\'s the difference between static and dynamic? Get straight answers before you start creating.', 160 ); diff --git a/src/app/(main)/(marketing)/page.tsx b/src/app/(main)/(marketing)/page.tsx index ababcd1..9687837 100644 --- a/src/app/(main)/(marketing)/page.tsx +++ b/src/app/(main)/(marketing)/page.tsx @@ -1,93 +1,126 @@ -import React from 'react'; -import type { Metadata } from 'next'; -import SeoJsonLd from '@/components/SeoJsonLd'; -import { organizationSchema, websiteSchema, softwareApplicationSchema, reviewSchema, aggregateRatingSchema } from '@/lib/schema'; -import { getFeaturedTestimonials, getAggregateRating } from '@/lib/testimonial-data'; -import HomePageClient from '@/components/marketing/HomePageClient'; - -function truncateAtWord(text: string, maxLength: number): string { - if (text.length <= maxLength) return text; - const truncated = text.slice(0, maxLength); - const lastSpace = truncated.lastIndexOf(' '); - return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated; -} - -export async function generateMetadata(): Promise { - const title = truncateAtWord('QR Master: Dynamic QR Generator', 60); - const description = truncateAtWord( - 'Create dynamic QR codes, track scans, and scale campaigns with secure analytics. Free advanced features, bulk generation, and custom branding available.', - 160 - ); - - return { - title, - description, - keywords: ['qr generator', 'free qr code generator', 'custom qr code generator', 'qr code maker', 'online qr code generator', 'dynamic qr code', 'qr code with logo'], - alternates: { - canonical: 'https://www.qrmaster.net/', - languages: { - 'x-default': 'https://www.qrmaster.net/', - en: 'https://www.qrmaster.net/', - de: 'https://www.qrmaster.net/qr-code-erstellen', - }, - }, - openGraph: { - title, - description, - url: 'https://www.qrmaster.net/', - type: 'website', - images: [ - { - url: 'https://www.qrmaster.net/og-image.png', - width: 1200, - height: 630, - alt: 'QR Master - Dynamic QR Code Generator and Analytics Platform', - }, - ], - }, - twitter: { - title, - description, - }, - }; -} - -export default function HomePage() { - const featuredTestimonials = getFeaturedTestimonials(); - const aggregateRating = getAggregateRating(); - const reviewSchemas = featuredTestimonials.map(t => reviewSchema(t)); - - return ( - <> - - - {/* Server-rendered SEO content for crawlers */} -
- -

- Create professional QR codes for your business with QR Master. Our dynamic QR code generator - lets you create trackable QR codes, edit destinations anytime, and view detailed analytics. - Perfect for restaurants, retail, events, and marketing campaigns. -

-

- Features include: Dynamic QR codes with real-time tracking, bulk QR code generation from Excel/CSV, - custom branding with colors and logos, advanced scan analytics showing device types and locations, - vCard QR codes for digital business cards, restaurant menu QR codes, and a free{' '} - barcode generator for EAN-13, UPC-A, and Code 128 barcodes. -

-

- Start free with 3 active dynamic QR codes and unlimited static codes. Upgrade to Pro for 50 codes - with advanced analytics, or Business for 500 codes with bulk creation and priority support. -

-
- - - - ); -} +import React from 'react'; +import type { Metadata } from 'next'; +import SeoJsonLd from '@/components/SeoJsonLd'; +import { + organizationSchema, + websiteSchema, + softwareApplicationSchema, + reviewSchema, + aggregateRatingSchema, +} from '@/lib/schema'; +import { + getFeaturedTestimonials, + getAggregateRating, +} from '@/lib/testimonial-data'; +import HomePageClient from '@/components/marketing/HomePageClient'; + +function truncateAtWord(text: string, maxLength: number): string { + if (text.length <= maxLength) return text; + const truncated = text.slice(0, maxLength); + const lastSpace = truncated.lastIndexOf(' '); + return lastSpace > 0 ? truncated.slice(0, lastSpace) : truncated; +} + +export async function generateMetadata(): Promise { + const title = truncateAtWord('QR Master - Free QR Code Generator', 60); + const description = truncateAtWord( + 'QR Master is a free QR code generator for dynamic QR codes, scan tracking, custom branding, bulk creation, and static QR tools.', + 160 + ); + + return { + title, + description, + keywords: [ + 'qr generator', + 'free qr code generator', + 'custom qr code generator', + 'qr code maker', + 'online qr code generator', + 'dynamic qr code', + 'qr code with logo', + 'barcode generator', + 'free barcode generator', + ], + alternates: { + canonical: 'https://www.qrmaster.net/', + languages: { + 'x-default': 'https://www.qrmaster.net/', + en: 'https://www.qrmaster.net/', + de: 'https://www.qrmaster.net/qr-code-erstellen', + }, + }, + openGraph: { + title, + description, + url: 'https://www.qrmaster.net/', + type: 'website', + images: [ + { + url: 'https://www.qrmaster.net/og-image.png', + width: 1200, + height: 630, + alt: 'QR Master - Dynamic QR Code Generator and Analytics Platform', + }, + ], + }, + twitter: { + title, + description, + }, + }; +} + +export default function HomePage() { + const featuredTestimonials = getFeaturedTestimonials(); + const aggregateRating = getAggregateRating(); + const reviewSchemas = featuredTestimonials.map((t) => reviewSchema(t)); + + return ( + <> + + + {/* Server-rendered SEO content for crawlers */} +
+

+ Create professional QR codes for your business with QR Master. Our + dynamic QR code generator lets you create trackable QR codes, edit + destinations anytime, and view detailed analytics. Perfect for + restaurants, retail, events, and marketing campaigns. +

+

+ Features include: Dynamic QR codes with real-time tracking, bulk QR + code generation from Excel/CSV, custom branding with colors and logos, + advanced scan analytics showing device types and locations, vCard QR + codes for digital business cards, restaurant menu QR codes, and a free{' '} + barcode generator for EAN-13, + UPC-A, and Code 128 barcodes. +

+

+ Popular QR Master workflows include the{' '} + + free dynamic QR code generator + + , QR code tracking, and the{' '} + custom QR code generator for + branded print campaigns. +

+

+ Start free with 3 active dynamic QR codes and unlimited static codes. + Upgrade to Pro for 50 codes with advanced analytics, or Business for + 500 codes with bulk creation and priority support. +

+
+ + + + ); +} diff --git a/src/app/(main)/(marketing)/qr-code-tracking/page.tsx b/src/app/(main)/(marketing)/qr-code-tracking/page.tsx index 7d91e55..4ae2fb9 100644 --- a/src/app/(main)/(marketing)/qr-code-tracking/page.tsx +++ b/src/app/(main)/(marketing)/qr-code-tracking/page.tsx @@ -1,590 +1,778 @@ -import React from 'react'; -import type { Metadata } from 'next'; -import { Button } from '@/components/ui/Button'; -import { Card } from '@/components/ui/Card'; -import SeoJsonLd from '@/components/SeoJsonLd'; -import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs'; -import { breadcrumbSchema } from '@/lib/schema'; -import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock'; -import { FAQSection } from '@/components/aeo/FAQSection'; -import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; -import { MarketingPageTracker, TrackedCtaLink } from '@/components/marketing/MarketingAnalytics'; - -export const metadata: Metadata = { - title: { - absolute: 'Free QR Code Tracking & Analytics – Track Every Scan', - }, - description: - 'Track QR code scans for free. See time, device, and location data for every scan. Use dynamic QR codes to measure printed campaigns and placements from one dashboard.', - keywords: - 'qr code tracking, qr code analytics, track qr scans, dynamic qr tracking, qr scan analytics', - alternates: { - canonical: 'https://www.qrmaster.net/qr-code-tracking', - languages: { - 'x-default': 'https://www.qrmaster.net/qr-code-tracking', - en: 'https://www.qrmaster.net/qr-code-tracking', - }, - }, - openGraph: { - title: 'Free QR Code Tracking & Analytics – Track Every Scan', - description: - 'Track QR code scans with analytics for time, device, and location context. Use dynamic QR codes to measure placements and campaigns.', - url: 'https://www.qrmaster.net/qr-code-tracking', - type: 'website', - images: ['/og-image.png'], - }, - twitter: { - title: 'QR Code Tracking & Analytics - Track Every Scan', - description: - 'Track QR code scans with analytics for time, device, and location context. Use dynamic QR codes to measure placements and campaigns.', - }, -}; - -const trackingFeatures = [ - { - title: 'Time-based scan activity', - description: - 'Review when scans happen so you can compare campaign bursts, peak service windows, or event timing.', - }, - { - title: 'Location context', - description: - 'See country, city, and region-level scan context in the dashboard to understand where scans are coming from.', - }, - { - title: 'Device mix', - description: - 'Understand whether scans are happening on phone or desktop-heavy traffic patterns and adapt landing pages accordingly.', - }, - { - title: 'Total and unique scan reporting', - description: - 'Use scan counts to understand overall activity and compare repeated scans with broader reach.', - }, - { - title: 'Placement-ready measurement', - description: - 'Track scans from print surfaces such as flyers, menus, signs, packaging, and event materials.', - }, - { - title: 'Dynamic QR workflow', - description: - 'Tracking works with dynamic QR codes that route through QR Master before the scanner reaches the final destination.', - }, -]; - -const trackingUseCases = [ - { - title: 'Marketing campaigns', - description: - 'Measure how printed placements such as flyers, signs, packaging inserts, or booth materials perform over time.', - benefits: ['Compare placements', 'Review campaign timing', 'See scan context in one dashboard'], - }, - { - title: 'Events', - description: - 'Track which event materials drive scans before, during, and after the event instead of treating every print touchpoint the same.', - benefits: ['Compare booth and signage scans', 'Watch event-day traffic', 'Keep destinations updateable'], - }, - { - title: 'Product and packaging', - description: - 'Measure which labels, inserts, or support links are getting scans after products leave the warehouse.', - benefits: ['Track support content usage', 'Compare packaging placements', 'Keep links current'], - }, - { - title: 'Restaurant and in-store surfaces', - description: - 'Review scans from menus, table cards, windows, or counters and compare when in-store prompts actually get used.', - benefits: ['Spot peak scan periods', 'Compare service surfaces', 'Keep menu links current'], - }, -]; - -const trackingComparison = [ - { feature: 'Destination can change later', static: false, dynamic: true }, - { feature: 'Scan analytics', static: false, dynamic: true }, - { feature: 'Placement comparison after print', static: false, dynamic: true }, - { feature: 'Reusable for campaigns that evolve', static: false, dynamic: true }, -]; - -const faqItems = [ - { - question: 'Can I track a static QR code?', - answer: - 'Static QR codes store the destination directly in the image, so QR Master cannot add the redirect step needed for tracking. Tracking requires a dynamic QR workflow.', - }, - { - question: 'What can I measure with QR code tracking?', - answer: - 'QR Master reports scan activity including time of scan, device type (mobile vs. desktop), and location context (country, city). You can also compare total scans vs. unique scans.', - }, - { - question: 'Why does tracking use a dynamic QR code?', - answer: - 'Tracking happens during the redirect step. A dynamic QR code routes the scan through QR Master first, which makes scan reporting possible before the user reaches the final destination.', - }, - { - question: 'When is QR code tracking most useful?', - answer: - 'It is most useful when you need to compare placements, campaign timing, or printed surfaces and want a measurable record instead of guessing which QR code prompt worked.', - }, - { - question: 'Is QR code scan tracking free?', - answer: - 'Yes — the Free plan includes basic scan tracking for up to 3 active dynamic QR codes. Pro and Business plans include extended scan history, more active codes, and full analytics.', - }, - { - question: 'Can I see unlimited scan history?', - answer: - 'Pro and Business plans include extended scan history and no limits on how many scans are tracked. The Free plan covers tracking for up to 3 active dynamic QR codes.', - }, -]; - -const softwareSchema = { - '@context': 'https://schema.org', - '@type': 'SoftwareApplication', - '@id': 'https://www.qrmaster.net/qr-code-tracking#software', - name: 'QR Master - QR Code Tracking & Analytics', - applicationCategory: 'BusinessApplication', - operatingSystem: 'Web Browser', - offers: { - '@type': 'Offer', - price: '0', - priceCurrency: 'EUR', - availability: 'https://schema.org/InStock', - }, - description: - 'Track QR code scans with analytics for time, device, and location context. Use dynamic QR codes to measure placements and campaigns.', - featureList: [ - 'Time-based scan reporting', - 'Location context in analytics', - 'Device mix reporting', - 'Total and unique scan reporting', - 'Dynamic QR workflow for trackable printed placements', - ], -}; - -const howToSchema = { - '@context': 'https://schema.org', - '@type': 'HowTo', - '@id': 'https://www.qrmaster.net/qr-code-tracking#howto', - name: 'How to track QR code scans', - datePublished: '2024-01-01', - dateModified: '2025-06-01', - author: { - '@type': 'Person', - name: 'Timo Knuth', - url: 'https://www.qrmaster.net/authors/timo', - }, - description: 'Create a dynamic QR code, deploy it, and review scan analytics from the QR Master dashboard.', - totalTime: 'PT5M', - step: [ - { - '@type': 'HowToStep', - position: 1, - name: 'Create a dynamic QR code', - text: 'Create a dynamic QR code in QR Master so the scan can route through the tracking step first.', - url: 'https://www.qrmaster.net/signup', - }, - { - '@type': 'HowToStep', - position: 2, - name: 'Deploy the QR code', - text: 'Place the QR code on the flyer, menu, sign, package, or event material you want to measure.', - }, - { - '@type': 'HowToStep', - position: 3, - name: 'Review analytics', - text: 'Open the dashboard to review scan context such as time, device, location, and total activity.', - }, - { - '@type': 'HowToStep', - position: 4, - name: 'Improve the next placement', - text: 'Use the scan patterns to improve your next campaign, placement, or destination update.', - }, - ], -}; - -const faqSchema = { - '@context': 'https://schema.org', - '@type': 'FAQPage', - '@id': 'https://www.qrmaster.net/qr-code-tracking#faq', - mainEntity: faqItems.map((item) => ({ - '@type': 'Question', - name: item.question, - acceptedAnswer: { - '@type': 'Answer', - text: item.answer, - }, - })), -}; - -const breadcrumbItems: BreadcrumbItem[] = [ - { name: 'Home', url: '/' }, - { name: 'QR Code Tracking', url: '/qr-code-tracking' }, -]; - -const relatedUseCaseLinks = [ - { - href: '/use-cases/real-estate-sign-qr-codes', - title: 'Real Estate Sign QR Codes', - description: - 'Compare sign, brochure, and open-house scans without blending every property source together.', - ctaLabel: 'Create your real estate QR code', - }, - { - href: '/use-cases/feedback-qr-codes', - title: 'Feedback QR Codes', - description: - 'Measure which service surfaces and follow-up prompts actually generate customer responses.', - ctaLabel: 'Create your feedback QR code', - }, - { - href: '/use-cases/coupon-qr-codes', - title: 'Coupon QR Codes', - description: - 'Tie printed discount placements to measurable scans so you can compare promotion performance.', - ctaLabel: 'Create your coupon QR code', - }, - { - href: '/qr-code-analytics', - title: 'QR Code Analytics Dashboard', - description: - 'Go deeper into placement-level reporting and offline campaign attribution.', - ctaLabel: 'Explore QR analytics', - }, - { - href: '/reprint-calculator', - title: 'QR Code Reprint Cost Calculator', - description: - 'See how much dynamic QR codes save vs reprinting static codes each campaign.', - ctaLabel: 'Calculate reprint savings', - }, - { - href: '/use-cases', - title: 'Explore the use-case hub', - description: - 'Browse the first commercial workflows built around dynamic updates and measurable scans.', - ctaLabel: 'Explore QR code use cases', - }, -]; - -export default function QRCodeTrackingPage() { - return ( - <> - - -
-
-
- -
-
-
- Trackable dynamic QR workflows -
- -
-

- Track every QR code scan with useful context -

-

- Use dynamic QR codes to measure scans by time, device, and location context, - so printed campaigns and physical placements stop being guesswork. -

-
- -
- {[ - 'Track printed placements with a dynamic QR workflow', - 'Review time, device, and location context', - 'Compare total and unique scan activity', - 'Use one dashboard to improve the next campaign or placement', - ].map((feature) => ( -
-
- - - -
- {feature} -
- ))} -
- -
- - - - - - -
-
- -
- -

Analytics overview

-
-
- Placement view - Flyer, sign, menu, package -
-
- Time trend - Hourly and daily patterns -
-
- Location context - Country, city, region -
-
- Device mix - Phone or desktop traffic -
-
-
-
- Dynamic QR required -
-
-
-
-
- -
- -
- -
- -
- -
-
-
-

What QR tracking helps you measure

-

- These are the analytics surfaces the current product experience already supports without inventing extra claims. -

-
- -
- {trackingFeatures.map((feature) => ( - -

{feature.title}

-

{feature.description}

-
- ))} -
-
-
- -
-
-
-

Tracking setup comparison

-

- Tracking is a dynamic QR workflow, not a static QR workflow with retroactive reporting. -

-
- - - - - - - - - - - - {trackingComparison.map((row) => ( - - - - - - ))} - -
CapabilityStatic QRDynamic QR tracking
{row.feature}{row.static ? 'Yes' : 'No'} - {row.dynamic ? 'Yes' : 'No'} -
-
-
-
- -
-
-
-

Where tracking is most useful

-

- Use tracking where physical surfaces or campaigns need measurable follow-through after they are deployed. -

-
- -
- {trackingUseCases.map((useCase) => ( - -

{useCase.title}

-

{useCase.description}

-
    - {useCase.benefits.map((benefit) => ( -
  • - - - - {benefit} -
  • - ))} -
-
- ))} -
-
-
- - {/* WHY QR TRACKING MATTERS — STATISTICS */} -
-
-
- - Research-backed impact -
-

- Why Tracking Makes QR Codes Measurable Marketing Assets -

-

- Without scan analytics, a printed QR code is invisible — you can't tell if your campaign placement is working. Tracking turns every scan into actionable data. -

- -
-
-
89% vs 33%
-

- Companies with strong omnichannel engagement — requiring closed-loop tracking from offline to online — retain 89% of their customers, compared to 33% for businesses without integrated tracking. -

-

- Source: Aberdeen Group — Omnichannel Customer Engagement Study -

-
- -
-
46%
-

- of small businesses identify print and direct mail errors as a major source of wasted marketing budget. QR tracking reveals which placements actually drive scans — so you reprint only what works. -

-

- Source: Data & Marketing Association (DMA) -

-
-
- -

- By Timo Knuth, QR Master · Last updated: June 2025 · Based on independent academic and industry research -

-
-
- - - -
-
-

Start tracking your QR codes today

-

- Measure scans with enough context to improve the next placement, campaign, or printed workflow. -

-
- - - - - - -
-
-
-
- - ); -} +import React from 'react'; +import type { Metadata } from 'next'; +import { Button } from '@/components/ui/Button'; +import { Card } from '@/components/ui/Card'; +import SeoJsonLd from '@/components/SeoJsonLd'; +import Breadcrumbs, { BreadcrumbItem } from '@/components/Breadcrumbs'; +import { breadcrumbSchema } from '@/lib/schema'; +import { AnswerFirstBlock } from '@/components/marketing/AnswerFirstBlock'; +import { FAQSection } from '@/components/aeo/FAQSection'; +import { GrowthLinksSection } from '@/components/marketing/GrowthLinksSection'; +import { + MarketingPageTracker, + TrackedCtaLink, +} from '@/components/marketing/MarketingAnalytics'; + +export const metadata: Metadata = { + title: { + absolute: 'QR Code Tracking - Track QR Code Scans Free', + }, + description: + 'Track QR code scans for free with QR code tracking and analytics. See time, device, and location context for printed campaigns and dynamic QR codes.', + keywords: + 'qr code tracking, qr code analytics, track qr scans, dynamic qr tracking, qr scan analytics', + alternates: { + canonical: 'https://www.qrmaster.net/qr-code-tracking', + languages: { + 'x-default': 'https://www.qrmaster.net/qr-code-tracking', + en: 'https://www.qrmaster.net/qr-code-tracking', + }, + }, + openGraph: { + title: 'QR Code Tracking - Track QR Code Scans Free', + description: + 'Track QR code scans with analytics for time, device, and location context. Use dynamic QR codes to measure placements and campaigns.', + url: 'https://www.qrmaster.net/qr-code-tracking', + type: 'website', + images: ['/og-image.png'], + }, + twitter: { + title: 'QR Code Tracking & Analytics - Track Every Scan', + description: + 'Track QR code scans with analytics for time, device, and location context. Use dynamic QR codes to measure placements and campaigns.', + }, +}; + +const trackingFeatures = [ + { + title: 'Time-based scan activity', + description: + 'Review when scans happen so you can compare campaign bursts, peak service windows, or event timing.', + }, + { + title: 'Location context', + description: + 'See country, city, and region-level scan context in the dashboard to understand where scans are coming from.', + }, + { + title: 'Device mix', + description: + 'Understand whether scans are happening on phone or desktop-heavy traffic patterns and adapt landing pages accordingly.', + }, + { + title: 'Total and unique scan reporting', + description: + 'Use scan counts to understand overall activity and compare repeated scans with broader reach.', + }, + { + title: 'Placement-ready measurement', + description: + 'Track scans from print surfaces such as flyers, menus, signs, packaging, and event materials.', + }, + { + title: 'Dynamic QR workflow', + description: + 'Tracking works with dynamic QR codes that route through QR Master before the scanner reaches the final destination.', + }, +]; + +const trackingUseCases = [ + { + title: 'Marketing campaigns', + description: + 'Measure how printed placements such as flyers, signs, packaging inserts, or booth materials perform over time.', + benefits: [ + 'Compare placements', + 'Review campaign timing', + 'See scan context in one dashboard', + ], + }, + { + title: 'Events', + description: + 'Track which event materials drive scans before, during, and after the event instead of treating every print touchpoint the same.', + benefits: [ + 'Compare booth and signage scans', + 'Watch event-day traffic', + 'Keep destinations updateable', + ], + }, + { + title: 'Product and packaging', + description: + 'Measure which labels, inserts, or support links are getting scans after products leave the warehouse.', + benefits: [ + 'Track support content usage', + 'Compare packaging placements', + 'Keep links current', + ], + }, + { + title: 'Restaurant and in-store surfaces', + description: + 'Review scans from menus, table cards, windows, or counters and compare when in-store prompts actually get used.', + benefits: [ + 'Spot peak scan periods', + 'Compare service surfaces', + 'Keep menu links current', + ], + }, +]; + +const trackingComparison = [ + { feature: 'Destination can change later', static: false, dynamic: true }, + { feature: 'Scan analytics', static: false, dynamic: true }, + { feature: 'Placement comparison after print', static: false, dynamic: true }, + { + feature: 'Reusable for campaigns that evolve', + static: false, + dynamic: true, + }, +]; + +const faqItems = [ + { + question: 'Can I track a static QR code?', + answer: + 'Static QR codes store the destination directly in the image, so QR Master cannot add the redirect step needed for tracking. Tracking requires a dynamic QR workflow.', + }, + { + question: 'What can I measure with QR code tracking?', + answer: + 'QR Master reports scan activity including time of scan, device type (mobile vs. desktop), and location context (country, city). You can also compare total scans vs. unique scans.', + }, + { + question: 'Why does tracking use a dynamic QR code?', + answer: + 'Tracking happens during the redirect step. A dynamic QR code routes the scan through QR Master first, which makes scan reporting possible before the user reaches the final destination.', + }, + { + question: 'When is QR code tracking most useful?', + answer: + 'It is most useful when you need to compare placements, campaign timing, or printed surfaces and want a measurable record instead of guessing which QR code prompt worked.', + }, + { + question: 'Is QR code scan tracking free?', + answer: + 'Yes — the Free plan includes basic scan tracking for up to 3 active dynamic QR codes. Pro and Business plans include extended scan history, more active codes, and full analytics.', + }, + { + question: 'Can I see unlimited scan history?', + answer: + 'Pro and Business plans include extended scan history and no limits on how many scans are tracked. The Free plan covers tracking for up to 3 active dynamic QR codes.', + }, +]; + +const softwareSchema = { + '@context': 'https://schema.org', + '@type': 'SoftwareApplication', + '@id': 'https://www.qrmaster.net/qr-code-tracking#software', + name: 'QR Master - QR Code Tracking & Analytics', + applicationCategory: 'BusinessApplication', + operatingSystem: 'Web Browser', + offers: { + '@type': 'Offer', + price: '0', + priceCurrency: 'EUR', + availability: 'https://schema.org/InStock', + }, + description: + 'Track QR code scans with analytics for time, device, and location context. Use dynamic QR codes to measure placements and campaigns.', + featureList: [ + 'Time-based scan reporting', + 'Location context in analytics', + 'Device mix reporting', + 'Total and unique scan reporting', + 'Dynamic QR workflow for trackable printed placements', + ], +}; + +const howToSchema = { + '@context': 'https://schema.org', + '@type': 'HowTo', + '@id': 'https://www.qrmaster.net/qr-code-tracking#howto', + name: 'How to track QR code scans', + datePublished: '2024-01-01', + dateModified: '2026-05-10', + author: { + '@type': 'Person', + name: 'Timo Knuth', + url: 'https://www.qrmaster.net/authors/timo', + }, + description: + 'Create a dynamic QR code, deploy it, and review scan analytics from the QR Master dashboard.', + totalTime: 'PT5M', + step: [ + { + '@type': 'HowToStep', + position: 1, + name: 'Create a dynamic QR code', + text: 'Create a dynamic QR code in QR Master so the scan can route through the tracking step first.', + url: 'https://www.qrmaster.net/signup', + }, + { + '@type': 'HowToStep', + position: 2, + name: 'Deploy the QR code', + text: 'Place the QR code on the flyer, menu, sign, package, or event material you want to measure.', + }, + { + '@type': 'HowToStep', + position: 3, + name: 'Review analytics', + text: 'Open the dashboard to review scan context such as time, device, location, and total activity.', + }, + { + '@type': 'HowToStep', + position: 4, + name: 'Improve the next placement', + text: 'Use the scan patterns to improve your next campaign, placement, or destination update.', + }, + ], +}; + +const faqSchema = { + '@context': 'https://schema.org', + '@type': 'FAQPage', + '@id': 'https://www.qrmaster.net/qr-code-tracking#faq', + mainEntity: faqItems.map((item) => ({ + '@type': 'Question', + name: item.question, + acceptedAnswer: { + '@type': 'Answer', + text: item.answer, + }, + })), +}; + +const breadcrumbItems: BreadcrumbItem[] = [ + { name: 'Home', url: '/' }, + { name: 'QR Code Tracking', url: '/qr-code-tracking' }, +]; + +const relatedUseCaseLinks = [ + { + href: '/use-cases/real-estate-sign-qr-codes', + title: 'Real Estate Sign QR Codes', + description: + 'Compare sign, brochure, and open-house scans without blending every property source together.', + ctaLabel: 'Create your real estate QR code', + }, + { + href: '/use-cases/feedback-qr-codes', + title: 'Feedback QR Codes', + description: + 'Measure which service surfaces and follow-up prompts actually generate customer responses.', + ctaLabel: 'Create your feedback QR code', + }, + { + href: '/use-cases/coupon-qr-codes', + title: 'Coupon QR Codes', + description: + 'Tie printed discount placements to measurable scans so you can compare promotion performance.', + ctaLabel: 'Create your coupon QR code', + }, + { + href: '/qr-code-analytics', + title: 'QR Code Analytics Dashboard', + description: + 'Go deeper into placement-level reporting and offline campaign attribution.', + ctaLabel: 'Explore QR analytics', + }, + { + href: '/reprint-calculator', + title: 'QR Code Reprint Cost Calculator', + description: + 'See how much dynamic QR codes save vs reprinting static codes each campaign.', + ctaLabel: 'Calculate reprint savings', + }, + { + href: '/use-cases', + title: 'Explore the use-case hub', + description: + 'Browse the first commercial workflows built around dynamic updates and measurable scans.', + ctaLabel: 'Explore QR code use cases', + }, +]; + +export default function QRCodeTrackingPage() { + return ( + <> + + +
+
+
+ +
+
+
+ Trackable dynamic QR workflows +
+ +
+

+ QR Code Tracking for Every Scan +

+

+ Track QR code scans by time, device, and location context + with dynamic QR codes, so printed campaigns and physical + placements stop being guesswork. +

+
+ +
+ {[ + 'Track printed placements with a dynamic QR workflow', + 'Review time, device, and location context', + 'Compare total and unique scan activity', + 'Use one dashboard to improve the next campaign or placement', + ].map((feature) => ( +
+
+ + + +
+ {feature} +
+ ))} +
+ +
+ + + + + + +
+
+ +
+ +

+ Analytics overview +

+
+
+ Placement view + + Flyer, sign, menu, package + +
+
+ Time trend + + Hourly and daily patterns + +
+
+ Location context + + Country, city, region + +
+
+ Device mix + + Phone or desktop traffic + +
+
+
+
+ Dynamic QR required +
+
+
+
+
+ +
+ +
+ +
+
+
+

+ Scan analytics workflow +

+

+ How to track QR code scans from print campaigns +

+

+ Create a dynamic QR code for each placement you want to measure, + label it by channel or surface, then compare scan activity from + the dashboard. This gives each flyer, sign, menu, package + insert, or event material its own measurable scan record. +

+
+ +
+ +

+ 1. Create trackable codes +

+

+ Use a dynamic QR code for each important placement so scans + route through QR Master before visitors reach the final page. +

+
+ +

+ 2. Label each placement +

+

+ Name codes by campaign, surface, location, or print batch so + the analytics stay useful when traffic starts coming in. +

+
+ +

+ 3. Compare scan results +

+

+ Review total scans, unique scans, devices, time patterns, and + location context to decide which printed placements deserve + more budget. +

+
+
+
+
+ +
+ +
+ +
+
+
+

+ What QR tracking helps you measure +

+

+ These are the analytics surfaces the current product experience + already supports without inventing extra claims. +

+
+ +
+ {trackingFeatures.map((feature) => ( + +

+ {feature.title} +

+

{feature.description}

+
+ ))} +
+
+
+ +
+
+
+

+ Tracking setup comparison +

+

+ Tracking is a dynamic QR workflow, not a static QR workflow with + retroactive reporting. +

+
+ + + + + + + + + + + + {trackingComparison.map((row) => ( + + + + + + ))} + +
+ Capability + + Static QR + + Dynamic QR tracking +
+ {row.feature} + + {row.static ? 'Yes' : 'No'} + + {row.dynamic ? 'Yes' : 'No'} +
+
+
+
+ +
+
+
+

+ Where tracking is most useful +

+

+ Use tracking where physical surfaces or campaigns need + measurable follow-through after they are deployed. +

+
+ +
+ {trackingUseCases.map((useCase) => ( + +

+ {useCase.title} +

+

{useCase.description}

+
    + {useCase.benefits.map((benefit) => ( +
  • + + + + {benefit} +
  • + ))} +
+
+ ))} +
+
+
+ + {/* WHY QR TRACKING MATTERS — STATISTICS */} +
+
+
+ + + + + Research-backed impact + +
+

+ Why Tracking Makes QR Codes Measurable Marketing Assets +

+

+ Without scan analytics, a printed QR code is invisible — you can't + tell if your campaign placement is working. Tracking turns every + scan into actionable data. +

+ +
+
+
+ 89% vs 33% +
+

+ Companies with strong omnichannel engagement — requiring + closed-loop tracking from offline to online — retain{' '} + 89% of their customers, compared to 33% for + businesses without integrated tracking. +

+

+ Source:{' '} + + Aberdeen Group + {' '} + — Omnichannel Customer Engagement Study +

+
+ +
+
+ 46% +
+

+ of small businesses identify print and direct mail errors as a + major source of wasted marketing budget. QR tracking reveals + which placements actually drive scans — so you reprint only + what works. +

+

+ Source:{' '} + + Data & Marketing Association (DMA) + +

+
+
+ +

+ By Timo Knuth, QR Master - Last updated: May 2026 - Based on + independent academic and industry research +

+
+
+ + + +
+
+

+ Start tracking your QR codes today +

+

+ Measure scans with enough context to improve the next placement, + campaign, or printed workflow. +

+
+ + + + + + +
+
+
+
+ + ); +} diff --git a/src/app/(main)/(marketing)/tools/barcode-generator/BarcodeGuide.tsx b/src/app/(main)/(marketing)/tools/barcode-generator/BarcodeGuide.tsx index e1694af..5f3875a 100644 --- a/src/app/(main)/(marketing)/tools/barcode-generator/BarcodeGuide.tsx +++ b/src/app/(main)/(marketing)/tools/barcode-generator/BarcodeGuide.tsx @@ -18,7 +18,7 @@ export function BarcodeGuide() {

- By Timo Knuth, QR Master · Last updated: April 2026 · GS1-verified content + By Timo Knuth, QR Master · Last updated: May 2026 · GS1-verified content

diff --git a/src/app/(main)/(marketing)/tools/barcode-generator/page.tsx b/src/app/(main)/(marketing)/tools/barcode-generator/page.tsx index 0f15de1..6e56194 100644 --- a/src/app/(main)/(marketing)/tools/barcode-generator/page.tsx +++ b/src/app/(main)/(marketing)/tools/barcode-generator/page.tsx @@ -1,382 +1,573 @@ - -import React from 'react'; -import type { Metadata } from 'next'; -import BarcodeGeneratorClient from './BarcodeGeneratorClient'; -import { BarcodeGuide } from './BarcodeGuide'; -import { Barcode as BarcodeIcon, Shield, Zap, Printer, Download, Share2, Sparkles, Sliders, Check } from 'lucide-react'; -import { ToolBreadcrumb } from '@/components/seo/BreadcrumbSchema'; -import { RelatedTools } from '@/components/marketing/RelatedTools'; -import { generateSoftwareAppSchema, generateFaqSchema } from '@/lib/schema-utils'; - -// SEO Optimized Metadata -export const metadata: Metadata = { - title: { - absolute: 'Free Barcode Generator Online – EAN, UPC, Code 128', - }, - description: 'Free online barcode generator for EAN-13, UPC-A, and Code 128 barcodes. Create scannable labels for retail, inventory, and logistics instantly. Download PNG or SVG — no signup required.', - keywords: ['barcode generator', 'online barcode maker', 'create barcode free', 'ean-13 generator', 'upc-a generator', 'code 128 generator', 'barcode creator', 'printable barcodes'], - alternates: { - canonical: 'https://www.qrmaster.net/tools/barcode-generator', - languages: { - 'x-default': 'https://www.qrmaster.net/tools/barcode-generator', - en: 'https://www.qrmaster.net/tools/barcode-generator', - }, - }, - openGraph: { - title: 'Barcode Generator: Create EAN, UPC & Code 128', - description: 'Barcode Generator: Create professional labels instantly. Free & Secured.', - url: 'https://www.qrmaster.net/tools/barcode-generator', - siteName: 'QR Master', - locale: 'en_US', - type: 'website', - images: [{ url: '/barcode-generator-preview.png', width: 1200, height: 630 }], - }, - twitter: { - card: 'summary_large_image', - title: 'Free Barcode Generator', - description: 'Create custom barcodes in seconds. Download high-quality PNG/SVG.', - }, - robots: { - index: true, - follow: true, - }, -}; - -// JSON-LD Structured Data -const jsonLd = { - '@context': 'https://schema.org', - '@graph': [ - generateSoftwareAppSchema( - 'Barcode Generator', - 'Generate custom printable barcodes instantly for EAN, UPC, Code 128 and more.', - '/barcode-generator-preview.png', - 'UtilitiesApplication' - ), - { - '@type': 'WebPage', - '@id': 'https://www.qrmaster.net/tools/barcode-generator', - name: 'Free Barcode Generator Online – EAN, UPC, Code 128', - description: 'A barcode generator converts any number or text into a scannable barcode image for retail labels, inventory, and product packaging. Supports EAN-13, UPC-A, and Code 128.', - speakable: { - '@type': 'SpeakableSpecification', - cssSelector: ['.bg-blue-50', 'h1'], - }, - author: { - '@type': 'Person', - name: 'Timo Knuth', - url: 'https://www.qrmaster.net/authors/timo', - }, - dateModified: '2026-04-27', - }, - { - '@type': 'HowTo', - name: 'How to Create a Barcode', - datePublished: '2024-06-01', - dateModified: '2026-04-27', - author: { - '@type': 'Person', - name: 'Timo Knuth', - url: 'https://www.qrmaster.net/authors/timo', - }, - description: 'Create custom barcodes for products or inventory.', - step: [ - { - '@type': 'HowToStep', - position: 1, - name: 'Enter Content', - text: 'Type or paste the numeric or alphanumeric data for your barcode.', - }, - { - '@type': 'HowToStep', - position: 2, - name: 'Select Format', - text: 'Choose the appropriate barcode type (e.g., Code 128 for general use, EAN-13 for retail).', - }, - { - '@type': 'HowToStep', - position: 3, - name: 'Customize Design', - text: 'Adjust the height and width of the barcode to fit your needs.', - }, - { - '@type': 'HowToStep', - position: 4, - name: 'Toggle Text', - text: 'Decide if you want the human-readable value to appear below the barcode.', - }, - { - '@type': 'HowToStep', - position: 5, - name: 'Download & Print', - text: 'Save your barcode as PNG or SVG and print it for labels or inventory.', - }, - ], - totalTime: 'PT20S', - }, - generateFaqSchema({ - 'What is a Barcode Generator?': { - question: 'What is a Barcode Generator?', - answer: 'A Barcode Generator is an online tool that converts numbers or text into scannable barcode images that can be used for products, labels, and inventory systems.', - }, - 'Is this barcode generator free to use?': { - question: 'Is this barcode generator free to use?', - answer: 'Yes, our online barcode generator is completely free to use with no hidden costs or sign-ups required. You can generate, download, and print barcodes instantly.', - }, - 'Which barcode format should I use?': { - question: 'Which barcode format should I use?', - answer: 'EAN-13 is standard for retail in Europe/Global. UPC-A is standard for retail in USA/Canada. Code 128 is best for logistics and internal tracking as it supports letters and numbers.', - }, - 'Can I download barcodes in vector format (SVG)?': { - question: 'Can I download barcodes in vector format (SVG)?', - answer: 'Yes! We offer SVG downloads. SVG files are vector-based, meaning they can be scaled to any size without losing quality—perfect for professional product packaging.', - }, - 'How do I generate a barcode online?': { - question: 'How do I generate a barcode online?', - answer: 'To generate a barcode online, enter your product number or text, select the desired barcode format (such as EAN-13 or Code 128), and click the generate button. The barcode will be created instantly.', - }, - 'Are generated barcodes scannable?': { - question: 'Are generated barcodes scannable?', - answer: 'Yes, barcodes generated with a proper barcode generator are fully scannable. We generate standard-compliant barcodes readable by any standard optical or laser barcode scanner.', - }, - 'Can I use these barcodes for Amazon (EAN/UPC)?': { - question: 'Can I use these barcodes for Amazon (EAN/UPC)?', - answer: 'You can generate the image for Amazon here if you already have your EAN/UPC number. However, you cannot "create" a valid global EAN number here—you must purchase those official numbers from GS1 to sell on major platforms like Amazon.', - }, - 'What is the difference between a barcode and a QR code?': { - question: 'What is the difference between a barcode and a QR code?', - answer: 'A barcode stores data horizontally (1D) and is mainly used for product IDs. A QR code stores data in 2D (matrix) and can hold much more information, such as URLs, vCards, or WiFi credentials.', - }, - }), - ], -}; - -export default function BarcodeGeneratorPage() { - return ( - <> -