Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
YouTube Security VideosŠkoda Peaq im Fahrest: DAS hätten wir nicht erwartet! | CHIP(21.09.2026 um 00:00 Uhr)
Sichere ProgrammierungBackups and other lies(20.09.2026 um 23:42 Uhr)
Sichere ProgrammierungOur linter's "safe" autofix would have silently disabled RBAC(20.09.2026 um 23:54 Uhr)
Sichere ProgrammierungTeaching our on-device assistant to say "I don't know"(20.09.2026 um 23:55 Uhr)
Sichere ProgrammierungThe Tracker Is the Spine(21.09.2026 um 00:02 Uhr)
YouTube Security VideosŠkoda Peaq im Fahrest: DAS hätten wir nicht erwartet! | CHIP(21.09.2026 um 00:00 Uhr)
Sichere ProgrammierungBackups and other lies(20.09.2026 um 23:42 Uhr)
Sichere ProgrammierungOur linter's "safe" autofix would have silently disabled RBAC(20.09.2026 um 23:54 Uhr)
Sichere ProgrammierungTeaching our on-device assistant to say "I don't know"(20.09.2026 um 23:55 Uhr)
Sichere ProgrammierungThe Tracker Is the Spine(21.09.2026 um 00:02 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Building in public, week 17: turning one feature into a page cluster (and the internal-linking layer nobody sees)

Reagiere als Erste:r — dein Feedback zählt!

Week 16 shipped the AI background remover: Rust-native, ort + ISNet + libvips, no Python. That was the feature. Week 17 was not about writing more of it. It was about the boring, high-leverage part that most side projects skip: turning one working feature into pages that can actually rank, and wiring those pages together so search engines can find them.

No new engine code this week. Just leverage on what already existed. Here is what that actually looked like.

The problem: a hub with nothing pointing at it

The background remover lives at /remove-background. That is the hub. The plan was classic hub-and-spoke: one general tool page, then use-case spokes that each target a specific intent (removing a signature background, prepping an Amazon product photo, and so on).

I built two spokes this week. But halfway through, I looked at how internal links actually worked on the site and found the real problem: nothing linked from the hub to the spokes. The spokes linked back to the hub in their body text, but the hub had no idea they existed. Neither did the ~180 converter pages.

Tool links on the site were hardcoded in a frontend constant, roughly:

export const IMAGE_TOOLS = [
  { label: "Compress JPG", href: "/compress/jpg", tool: "compress" },
  { label: "Resize Image", href: "/resize-image", tool: "resize" },
  { label: "Crop Image", href: "/crop-image", tool: "crop" },
  { label: "Images to PDF", href: "/images-to-pdf", tool: "convert" },
] as const;

That list covered the converter tools. It did not include the background remover or its spokes at all. So the new pages were orphans: reachable only through the sitemap, with no internal links carrying any signal to them. For a domain that is still young and still earning Google's trust, orphan pages get discovered slowly and rank even slower.

The fix: one constant as the source of truth

Instead of hardcoding links in three different places, I made a single constant describe the whole cluster:

export const BACKGROUND_TOOLS = [
  { label: "Background Remover", href: "/background-remover" },
  { label: "Signature Background", href: "/remove-signature-background" },
  { label: "Amazon Product Photo", href: "/amazon-product-photo-background" },
] as const;

Then a small server component renders it, with an exclude prop so each page drops itself from the list:

export default function BackgroundTools({ exclude }: { exclude?: string }) {
  const tools = BACKGROUND_TOOLS.filter((t) => t.href !== exclude);
  if (tools.length === 0) return null;

  return (
    <section>
      <h2>Background Removal</h2>
      <div>
        {tools.map(({ label, href }) => (
          <Link key={href} href={href}>{label}</Link>
        ))}
      </div>
    </section>
  );
}

The nice part is that the same constant became the source of truth for detecting a background-removal page too. The main layout used to repeat the same array-of-slugs check three separate times. That collapsed into one line:

const isBgRemoval = BACKGROUND_TOOLS.some((tool) => tool.href === `/${mode}`);

So now: the hub links to both spokes, each spoke links to the hub and its sibling, and the whole thing renders only on background-removal pages. Adding a fourth spoke later is one line in the constant and it is cross-linked everywhere automatically. I also added the same list as a footer column, which puts the links on every page of the site, not just the cluster.

The bug that only shows up in production

The two spokes are stored as structured content in the database, and each section body is rendered with dangerouslySetInnerHTML inside a <p>. On one spoke I added a small "before you upload" checklist as a <ul>. It looked fine locally. In production, React threw a hydration mismatch.

The reason is plain once you see it: a <ul> is not valid inside a <p>. The browser silently auto-closes the paragraph before the list, so the DOM the browser builds does not match the HTML React rendered on the server, and hydration fails. The fix was to keep the section body to inline content only, so the checklist became <br>-separated lines instead of a real list.

The lesson I actually kept: I added a build-time guard that scans every section body for block-level tags (ul, ol, li, div, table, headings) and fails the build if it finds one. The class of bug is now impossible to ship again, which matters more than the one fix.

The honest numbers

Building in public means posting the numbers even when they are boring or bad.

  • Background pages live: 3 (hub + 2 spokes). The plan asked for 1 or 2, so this part went well.
  • Benchmark on the real VPS: the background remover runs at about p50 2.4s, p95 9.6s per image on a 4-core box.
  • AI citations: the site is cited 75 times across Microsoft Copilot, mostly on HEIC content. That is visibility that never shows up in a rank tracker, and I only found it by looking.
  • Google: still sandboxed. Impressions exist, positions are deep (average around the mid-40s), clicks are a trickle. Bing, meanwhile, ranks the same pages on page one. Same content, different trust curve. This is normal for a young domain and I am not fighting it, just waiting it out while the content compounds.

What week 18 looks like

More spokes, but slowly. Google's spam updates punish thin template-swap pages, so the rule is one or two good pages with genuine unique data, not ten shells. On the list: a couple more use-case spokes, a low-competition webp remove background page I found in my keyword data, and continuing the slow grind of backlinks to lift domain authority, which is the real ceiling right now.

The feature was week 16. The leverage was week 17. If you are building something similar, the thing I would repeat is this: shipping the feature is the easy half. Making it findable, and keeping the pages honestly connected, is the half that actually decides whether anyone ever sees it.

You can try the background remover here: https://convertifyapp.net/remove-background

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Building in public, week 17: turning one feature into a page cluster (and the internal-linking layer nobody sees)

Thematisch verwandte Begriffe: Building, public, week, turning · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-93957 | A vulnerability has been found in olivier-ls PHP-FTS up to 1.1.3. This a…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick