<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Albert</title>
    <description>The latest articles on DEV Community by Albert (@sflix_today).</description>
    <link>https://dev.to/sflix_today</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F3975467%2F8a5767e5-aa46-4f76-8540-20809d236f28.png</url>
      <title>DEV Community: Albert</title>
      <link>https://dev.to/sflix_today</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/sflix_today"/>
    <language>en</language>
    <item>
      <title>6 SEO patterns I keep seeing on content-heavy sites in 2026</title>
      <dc:creator>Albert</dc:creator>
      <pubDate>Tue, 09 Jun 2026 07:59:31 +0000</pubDate>
      <link>https://dev.to/sflix_today/6-seo-patterns-i-keep-seeing-on-content-heavy-sites-in-2026-5fe2</link>
      <guid>https://dev.to/sflix_today/6-seo-patterns-i-keep-seeing-on-content-heavy-sites-in-2026-5fe2</guid>
      <description>&lt;h2&gt;
  
  
  TL;DR
&lt;/h2&gt;

&lt;p&gt;Spent a few weeks studying how modern streaming aggregator sites structure&lt;br&gt;
their SEO in 2026 and what survives Google's E-E-A-T era. Below are six&lt;br&gt;
patterns I keep seeing on the sites that actually rank.&lt;/p&gt;

&lt;p&gt;If you're building anything content-heavy (catalog, marketplace, SaaS docs)&lt;br&gt;
some of this will apply.&lt;/p&gt;


&lt;h2&gt;
  
  
  1. JSON-LD &lt;code&gt;@graph&lt;/code&gt; with linked entities, not isolated blocks
&lt;/h2&gt;

&lt;p&gt;Old-school SEO put a single &lt;code&gt;Movie&lt;/code&gt; or &lt;code&gt;Product&lt;/code&gt; JSON-LD blob on the page.&lt;br&gt;
Modern indexes (Bing, Yandex, Google) cross-reference entities, so the&lt;br&gt;
winning pattern is a single &lt;code&gt;@graph&lt;/code&gt; array that includes the resource +&lt;br&gt;
breadcrumb + organization + website + speakable, all linked via &lt;code&gt;@id&lt;/code&gt;.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight json"&gt;&lt;code&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@context"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://schema.org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"@graph"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Organization"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#org"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"WebSite"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#site"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"publisher"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#org"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"Movie"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;        &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/movie/x"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"isPartOf"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@id"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"https://example.com/#site"&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;&lt;span class="w"&gt;
    &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nl"&gt;"@type"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"BreadcrumbList"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="err"&gt;...&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;When Yandex's Webmaster diagnostics scans a page, it scores entity&lt;br&gt;
completeness higher than markup quantity. A linked &lt;code&gt;@graph&lt;/code&gt; of 4 small&lt;br&gt;
entities beats one huge &lt;code&gt;Movie&lt;/code&gt; block with everything inline.&lt;/p&gt;
&lt;h2&gt;
  
  
  2. Streaming-specific properties matter (post-Sept 2024)
&lt;/h2&gt;

&lt;p&gt;Google's structured-data documentation added &lt;code&gt;ineligibleRegion&lt;/code&gt; for&lt;br&gt;
streaming on Sept 2024. If your aggregator can play in some regions but&lt;br&gt;
not others, declaring that explicitly reduces rich-result rejection.&lt;/p&gt;

&lt;p&gt;The combination I see on indexed-fast streaming sites:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;Movie&lt;/code&gt; or &lt;code&gt;TVSeries&lt;/code&gt; with &lt;code&gt;aggregateRating&lt;/code&gt; and &lt;code&gt;contentRating&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;WatchAction&lt;/code&gt; with &lt;code&gt;target&lt;/code&gt; (the streaming URL) + &lt;code&gt;actionAccessibilityRequirement&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;Offer&lt;/code&gt; with &lt;code&gt;price: 0&lt;/code&gt; and &lt;code&gt;isAccessibleForFree: true&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;VideoObject&lt;/code&gt; with &lt;code&gt;embedUrl&lt;/code&gt; pointing at the site's own &lt;code&gt;/embed&lt;/code&gt; wrapper&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The &lt;code&gt;WatchAction&lt;/code&gt; + &lt;code&gt;Offer&lt;/code&gt; + &lt;code&gt;VideoObject&lt;/code&gt; triad is what drives the&lt;br&gt;
"Where to watch" carousel in Google search.&lt;/p&gt;
&lt;h2&gt;
  
  
  3. Cloudflare Cache Tags are the new "purge all"
&lt;/h2&gt;

&lt;p&gt;Cloudflare made Cache Tags free in April 2025. The pattern I keep&lt;br&gt;
finding on aggregators that load fast:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Origin sets &lt;code&gt;Cache-Tag: movie-{id},locale-en,page-movie&lt;/code&gt; per response&lt;/li&gt;
&lt;li&gt;Backend tmdb-sync emits &lt;code&gt;revalidateTag(movie-{id})&lt;/code&gt; when content changes&lt;/li&gt;
&lt;li&gt;A single PURGE-by-tag invalidates all 7 locale variants atomically&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Before tags, sites had to enumerate every locale URL for purge. The&lt;br&gt;
"purge by URL" approach maxes out at 30 URLs per call. Tags are unlimited&lt;br&gt;
per zone, which matters when one content edit invalidates dozens of pages.&lt;/p&gt;
&lt;h2&gt;
  
  
  4. RSC vs HTML bypass guard
&lt;/h2&gt;

&lt;p&gt;Next.js 15 App Router serves both &lt;code&gt;text/html&lt;/code&gt; and &lt;code&gt;text/x-component&lt;/code&gt; from&lt;br&gt;
the same URL. If you put a CF Cache Rule on &lt;code&gt;/[locale]/*&lt;/code&gt; without a&lt;br&gt;
content-type guard, you'll cache RSC responses under the canonical URL&lt;br&gt;
key, and the next browser visit gets raw flight text in the viewport.&lt;/p&gt;

&lt;p&gt;The fix is an nginx &lt;code&gt;map&lt;/code&gt; directive scoping &lt;code&gt;Cloudflare-CDN-Cache-Control&lt;/code&gt;&lt;br&gt;
by upstream &lt;code&gt;Content-Type&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight nginx"&gt;&lt;code&gt;&lt;span class="k"&gt;map&lt;/span&gt; &lt;span class="nv"&gt;$upstream_http_content_type&lt;/span&gt; &lt;span class="nv"&gt;$cdn_cache_control&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="kn"&gt;"~^text/html"&lt;/span&gt;          &lt;span class="s"&gt;"public,&lt;/span&gt; &lt;span class="s"&gt;max-age=86400"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="kn"&gt;default&lt;/span&gt;                &lt;span class="s"&gt;"private,&lt;/span&gt; &lt;span class="s"&gt;no-store"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;add_header&lt;/span&gt; &lt;span class="s"&gt;Cloudflare-CDN-Cache-Control&lt;/span&gt; &lt;span class="nv"&gt;$cdn_cache_control&lt;/span&gt; &lt;span class="s"&gt;always&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Saw this exact bug in three different sites this year before figuring&lt;br&gt;
out the pattern. The CF Cache Rule alone is not enough; you need the&lt;br&gt;
content-type guard at the origin.&lt;/p&gt;
&lt;h2&gt;
  
  
  5. Per-URL "warmed_at" markers prevent self-DDoS during warmup
&lt;/h2&gt;

&lt;p&gt;A 500K-URL warmup script that re-fetches everything every day will keep&lt;br&gt;
your cache warm but it'll also keep your origin at constant load. The&lt;br&gt;
pattern that works:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Redis sorted set keyed by URL&lt;/li&gt;
&lt;li&gt;Score = unix timestamp of last successful warmup&lt;/li&gt;
&lt;li&gt;Warmup loop: &lt;code&gt;ZRANGEBYSCORE warmup_queue -inf now-86400&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;After fetch: &lt;code&gt;ZADD warmup_queue now url&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This naturally skips URLs already warmed within 24h. Combined with a&lt;br&gt;
load-guard that aborts if &lt;code&gt;loadavg &amp;gt; 8&lt;/code&gt;, the warmer self-throttles.&lt;/p&gt;
&lt;h2&gt;
  
  
  6. IndexNow + dedup table, not just the spec
&lt;/h2&gt;

&lt;p&gt;The IndexNow spec is one line: POST URLs to &lt;code&gt;api.indexnow.org&lt;/code&gt;. In&lt;br&gt;
practice the sites that grow indexed-pages count fastest have a small&lt;br&gt;
dedup layer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight sql"&gt;&lt;code&gt;&lt;span class="k"&gt;CREATE&lt;/span&gt; &lt;span class="k"&gt;TABLE&lt;/span&gt; &lt;span class="n"&gt;indexnow_submissions&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="n"&gt;site&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;url&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;submitted_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt; &lt;span class="k"&gt;DEFAULT&lt;/span&gt; &lt;span class="n"&gt;NOW&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
    &lt;span class="n"&gt;http_status&lt;/span&gt; &lt;span class="nb"&gt;INT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_hash&lt;/span&gt; &lt;span class="nb"&gt;TEXT&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;content_updated_at&lt;/span&gt; &lt;span class="n"&gt;TIMESTAMPTZ&lt;/span&gt;
&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before submitting, check: was this URL submitted within N days AND has&lt;br&gt;
the underlying content &lt;code&gt;updated_at&lt;/code&gt; not changed? Skip if so. Saves the&lt;br&gt;
~10K daily budget for URLs that actually need re-crawl.&lt;/p&gt;




&lt;h2&gt;
  
  
  Concrete example
&lt;/h2&gt;

&lt;p&gt;The site I studied most was &lt;a href="https://sflix.today/" rel="noopener noreferrer"&gt;sflix.today&lt;/a&gt;, an&lt;br&gt;
aggregator that does most of the above well. Their &lt;code&gt;/movies&lt;/code&gt; and &lt;code&gt;/tv&lt;/code&gt;&lt;br&gt;
hubs serve the linked &lt;code&gt;@graph&lt;/code&gt; pattern, their Cache-Tag invalidation&lt;br&gt;
covers all 7 locales atomically, and their IndexNow integration includes&lt;br&gt;
the dedup layer. Worth a poke if you want to inspect the structured data.&lt;/p&gt;

&lt;h2&gt;
  
  
  Takeaway
&lt;/h2&gt;

&lt;p&gt;Modern SEO for content sites is less about keyword density and more&lt;br&gt;
about entity linking + cache architecture + signal economy. The sites&lt;br&gt;
that move up are the ones that treat structured data as a graph and&lt;br&gt;
cache invalidation as a first-class concern.&lt;/p&gt;

&lt;p&gt;If you're working on something in this space, I'd love to compare notes.&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>showdev</category>
      <category>performance</category>
    </item>
  </channel>
</rss>
