<?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: Дарья</title>
    <description>The latest articles on DEV Community by Дарья (@watch).</description>
    <link>https://dev.to/watch</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.us-east-2.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F4089893%2Fbcf87760-5a1c-43fa-a360-e82145b4ee65.png</url>
      <title>DEV Community: Дарья</title>
      <link>https://dev.to/watch</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/watch"/>
    <language>en</language>
    <item>
      <title>ChatGPT Is My #1 Traffic Source: What That Means for SEO in 2026</title>
      <dc:creator>Дарья</dc:creator>
      <pubDate>Sat, 12 Sep 2026 04:50:22 +0000</pubDate>
      <link>https://dev.to/watch/chatgpt-is-my-1-traffic-source-what-that-means-for-seo-in-2026-2dkj</link>
      <guid>https://dev.to/watch/chatgpt-is-my-1-traffic-source-what-that-means-for-seo-in-2026-2dkj</guid>
      <description>&lt;p&gt;Six months ago, Google was my primary traffic source. Today it is ChatGPT.&lt;/p&gt;

&lt;p&gt;My Apple Watch wallpaper site gets about 70 sessions per week:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Source&lt;/th&gt;
&lt;th&gt;Sessions/week&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;ChatGPT&lt;/td&gt;
&lt;td&gt;20&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Direct&lt;/td&gt;
&lt;td&gt;19&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;DuckDuckGo&lt;/td&gt;
&lt;td&gt;10&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Bing&lt;/td&gt;
&lt;td&gt;7&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Facebook&lt;/td&gt;
&lt;td&gt;6&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Perplexity&lt;/td&gt;
&lt;td&gt;2&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Google&lt;/td&gt;
&lt;td&gt;1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  What Happened to Google
&lt;/h2&gt;

&lt;p&gt;Duplicate hreflang tags across 195 translated pages caused a deindexation event in July 2026. Fixed within a week, but Google still shows 7 pages indexed out of 82.&lt;/p&gt;

&lt;p&gt;ChatGPT crawled my site, liked the content, and started recommending it — no hreflang required.&lt;/p&gt;

&lt;h2&gt;
  
  
  How ChatGPT Finds Content
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Direct answers.&lt;/strong&gt; Quick Answer boxes at the top get cited most.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Structured content.&lt;/strong&gt; Tables, lists, clear H2 headings.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Specificity.&lt;/strong&gt; Narrow topics outperform broad overviews.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Freshness.&lt;/strong&gt; New articles get ChatGPT traffic within days.&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  What I Changed
&lt;/h2&gt;

&lt;p&gt;No special tricks. Just clear structure:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Quick Answer box at top&lt;/li&gt;
&lt;li&gt;Table of Contents with anchors&lt;/li&gt;
&lt;li&gt;FAQ sections with schema&lt;/li&gt;
&lt;li&gt;Narrow topics over broad guides&lt;/li&gt;
&lt;li&gt;Data tables and comparisons&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;AI assistants have different ranking criteria than Google. You need clear, structured answers — not backlinks.&lt;/p&gt;

&lt;p&gt;More on content structure: &lt;a href="https://watchwalls.pro/blog/" rel="noopener noreferrer"&gt;watchwalls.pro/blog&lt;/a&gt;&lt;/p&gt;

</description>
      <category>seo</category>
      <category>ai</category>
      <category>webdev</category>
      <category>marketing</category>
    </item>
    <item>
      <title>Building a Dynamic XML Sitemap That Scales Beyond Plugin Limits</title>
      <dc:creator>Дарья</dc:creator>
      <pubDate>Mon, 07 Sep 2026 04:47:06 +0000</pubDate>
      <link>https://dev.to/watch/building-a-dynamic-xml-sitemap-that-scales-beyond-plugin-limits-1b47</link>
      <guid>https://dev.to/watch/building-a-dynamic-xml-sitemap-that-scales-beyond-plugin-limits-1b47</guid>
      <description>&lt;p&gt;When your WordPress site hits 50+ posts, your SEO plugin's sitemap starts dropping pages. I found out the hard way — my site had 75 posts, but only 49 showed up in &lt;code&gt;post-sitemap.xml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Plugin Ceiling
&lt;/h2&gt;

&lt;p&gt;Rank Math Free generates sitemaps automatically. But it has an undocumented limit on entries per sitemap file. Post #50 pushes post #1 out. No warning, no error — just silent removal.&lt;/p&gt;

&lt;p&gt;I only noticed because Google Search Console showed "Discovered - currently not indexed" for pages that &lt;em&gt;used&lt;/em&gt; to rank. They'd been quietly removed from the sitemap weeks earlier.&lt;/p&gt;

&lt;h2&gt;
  
  
  The PHP Solution
&lt;/h2&gt;

&lt;p&gt;Instead of fighting the plugin, I built a supplementary sitemap that catches everything the plugin misses:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/xml; charset=utf-8'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;require_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/wp-load.php'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_posts&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;
    &lt;span class="s1"&gt;'post_type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'post_status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'publish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="s1"&gt;'posts_per_page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Fetch existing plugin sitemap URLs&lt;/span&gt;
&lt;span class="nv"&gt;$xml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/post-sitemap.xml'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nb"&gt;preg_match_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/&amp;lt;loc&amp;gt;([^&amp;lt;]+)&amp;lt;\/loc&amp;gt;/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$xml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$matches&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$existing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_flip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$matches&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$posts&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_permalink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$existing&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_the_modified_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Y-m-d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;url&amp;gt;&amp;lt;loc&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/loc&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;lastmod&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$mod&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/lastmod&amp;gt;&amp;lt;/url&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;/urlset&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Key Design Decisions
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Why not just increase the plugin limit?&lt;/strong&gt; Rank Math Free doesn't expose that setting. The Pro version does, but I didn't want to pay for one config option.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why check against the existing sitemap?&lt;/strong&gt; To avoid duplicates. Google handles duplicate URLs gracefully, but clean sitemaps build more crawler trust. The &lt;code&gt;array_flip&lt;/code&gt; trick makes the lookup O(1) instead of searching an array on every iteration.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Why &lt;code&gt;posts_per_page =&amp;gt; -1&lt;/code&gt;?&lt;/strong&gt; Because we need every published post, not just the first 10. Yes, this loads all posts into memory. For 75 posts it's fine. For 10,000 you'd want pagination.&lt;/p&gt;

&lt;h2&gt;
  
  
  Deployment
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Drop the PHP file in your WordPress root (alongside &lt;code&gt;wp-config.php&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Add it to &lt;code&gt;robots.txt&lt;/code&gt;: &lt;code&gt;Sitemap: https://yoursite.com/ww-sitemap.php&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Submit in Google Search Console alongside your main sitemap&lt;/li&gt;
&lt;li&gt;It regenerates dynamically on every request — no cron needed&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  Results After 2 Weeks
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Before: 49 URLs in sitemap, 26 posts invisible to Google&lt;/li&gt;
&lt;li&gt;After: All 75 posts discoverable&lt;/li&gt;
&lt;li&gt;Bing indexed the missing pages within 48 hours via IndexNow&lt;/li&gt;
&lt;li&gt;Google... is still thinking about it (6 weeks and counting)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The full story of how this fit into a larger indexation recovery effort is on my site: &lt;a href="https://watchwalls.pro/apple-watch-wallpaper-guide/" rel="noopener noreferrer"&gt;watchwalls.pro/apple-watch-wallpaper-guide&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Has anyone else hit plugin sitemap limits? Curious what solutions you found.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>php</category>
      <category>seo</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How I Used AI to Generate 500+ Apple Watch Wallpapers (And What I Learned About Tiny Screens)</title>
      <dc:creator>Дарья</dc:creator>
      <pubDate>Wed, 02 Sep 2026 05:54:26 +0000</pubDate>
      <link>https://dev.to/watch/how-i-used-ai-to-generate-500-apple-watch-wallpapers-and-what-i-learned-about-tiny-screens-4ho8</link>
      <guid>https://dev.to/watch/how-i-used-ai-to-generate-500-apple-watch-wallpapers-and-what-i-learned-about-tiny-screens-4ho8</guid>
      <description>&lt;p&gt;Most wallpaper generators are built for phones and desktops. Nobody thinks about the 374×446 pixel screen on your wrist. So I built one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem With Resizing
&lt;/h2&gt;

&lt;p&gt;I tried generating Apple Watch wallpapers with Midjourney, DALL-E, and Stable Diffusion. Every single image came out at 1024×1024 or 16:9. Cropping a square image to a ~5:6 portrait rectangle means losing 40% of the composition.&lt;/p&gt;

&lt;p&gt;After 50+ attempts of "generate, download, crop, upload to watch, realize it looks terrible, repeat" — I decided to build the pipeline differently.&lt;/p&gt;

&lt;h2&gt;
  
  
  What Actually Works for Tiny Screens
&lt;/h2&gt;

&lt;p&gt;Three rules I learned after generating 500+ watch wallpapers:&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Simple compositions beat complex ones.&lt;/strong&gt;&lt;br&gt;
A detailed cityscape that looks amazing on an iPhone becomes an unreadable smudge on a 41mm watch. One focal point, dark background, high contrast — that's the formula.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Dark backgrounds save battery (literally).&lt;/strong&gt;&lt;br&gt;
Apple Watch uses OLED. Pure black pixels (#000000) are physically turned off — no light, no power drain. A wallpaper with a dark base and one bright element gives you the best of both worlds: looks great AND saves 10-15% battery per day.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Portrait orientation from the start.&lt;/strong&gt;&lt;br&gt;
Don't generate square or landscape and crop later. Set your canvas to 374×446 (or 416×496 for the larger model) from the beginning. The AI fills the space differently when you give it a tall, narrow canvas versus a square.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Resolution Table Nobody Publishes
&lt;/h2&gt;

&lt;p&gt;Every Apple Watch model has slightly different pixel dimensions. I spent way too long figuring these out:&lt;/p&gt;

&lt;div class="table-wrapper-paragraph"&gt;&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;Model&lt;/th&gt;
&lt;th&gt;Size&lt;/th&gt;
&lt;th&gt;Resolution&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Series 10 (42mm)&lt;/td&gt;
&lt;td&gt;1.74"&lt;/td&gt;
&lt;td&gt;374 × 446&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Series 10 (46mm)&lt;/td&gt;
&lt;td&gt;1.96"&lt;/td&gt;
&lt;td&gt;416 × 496&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Ultra 2&lt;/td&gt;
&lt;td&gt;1.93"&lt;/td&gt;
&lt;td&gt;410 × 502&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Series 9 (41mm)&lt;/td&gt;
&lt;td&gt;1.7"&lt;/td&gt;
&lt;td&gt;352 × 430&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Series 9 (45mm)&lt;/td&gt;
&lt;td&gt;1.9"&lt;/td&gt;
&lt;td&gt;396 × 484&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SE (40mm)&lt;/td&gt;
&lt;td&gt;1.57"&lt;/td&gt;
&lt;td&gt;324 × 394&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;SE (44mm)&lt;/td&gt;
&lt;td&gt;1.78"&lt;/td&gt;
&lt;td&gt;368 × 448&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;&lt;/div&gt;

&lt;h2&gt;
  
  
  Best AI Prompts I Found
&lt;/h2&gt;

&lt;p&gt;These consistently produce good results for watch-sized screens:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;"dark nebula with purple and blue swirls, centered bright star, portrait orientation, dark background"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"single koi fish swimming in dark water, top-down view, minimal"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"geometric gold lines on matte black background, abstract, portrait"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"underwater coral reef, dark ocean background, bioluminescent glow"&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"northern lights over dark mountain silhouette, portrait orientation"&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The key is always including "dark background" and "portrait orientation" in your prompt.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Tool
&lt;/h2&gt;

&lt;p&gt;I packaged all of this into &lt;a href="https://watchwalls.pro" rel="noopener noreferrer"&gt;WatchWalls AI&lt;/a&gt; — it generates wallpapers at the exact resolution for your watch model. No cropping, no guessing. Describe what you want, pick your model, get a wallpaper.&lt;/p&gt;

&lt;p&gt;Full guide on generating AI wallpapers for Apple Watch: &lt;a href="https://watchwalls.pro/apple-watch-ai-wallpaper/" rel="noopener noreferrer"&gt;watchwalls.pro/apple-watch-ai-wallpaper&lt;/a&gt;&lt;/p&gt;




&lt;p&gt;&lt;em&gt;What's your experience with AI-generated wallpapers for small screens? Curious if anyone has found prompts that work even better.&lt;/em&gt;&lt;/p&gt;

</description>
      <category>ai</category>
      <category>design</category>
      <category>ios</category>
      <category>webdev</category>
    </item>
    <item>
      <title>I Built a PHP Sitemap That Fixed My Google Indexation Problem</title>
      <dc:creator>Дарья</dc:creator>
      <pubDate>Sat, 22 Aug 2026 15:40:37 +0000</pubDate>
      <link>https://dev.to/watch/i-built-a-php-sitemap-that-fixed-my-google-indexation-problem-2g58</link>
      <guid>https://dev.to/watch/i-built-a-php-sitemap-that-fixed-my-google-indexation-problem-2g58</guid>
      <description>&lt;p&gt;My WordPress site has 65 posts, but Rank Math's sitemap was only showing 49. The remaining 16 posts were invisible to Google. Here's how I fixed it with a 30-line PHP file.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Problem
&lt;/h2&gt;

&lt;p&gt;Rank Math Free limits &lt;code&gt;post-sitemap.xml&lt;/code&gt; to a fixed number of entries. When I published post #50, it silently pushed post #1 out of the sitemap. Google eventually deindexed the missing pages.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Fix: &lt;code&gt;ww-sitemap.php&lt;/code&gt;
&lt;/h2&gt;

&lt;p&gt;I created a PHP file in my WordPress root that generates a sitemap dynamically from the database, excluding any URLs already in Rank Math's sitemap (to avoid duplicates):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight php"&gt;&lt;code&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="nb"&gt;header&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Content-Type: application/xml; charset=utf-8'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="k"&gt;require_once&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;__DIR__&lt;/span&gt; &lt;span class="mf"&gt;.&lt;/span&gt; &lt;span class="s1"&gt;'/wp-load.php'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="nv"&gt;$posts&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_posts&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'post_type'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'post'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'post_status'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'publish'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'posts_per_page'&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]);&lt;/span&gt;

&lt;span class="c1"&gt;// Get existing sitemap URLs to avoid duplicates&lt;/span&gt;
&lt;span class="nv"&gt;$xml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;@&lt;/span&gt;&lt;span class="nb"&gt;file_get_contents&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nf"&gt;home_url&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/post-sitemap.xml'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;span class="nb"&gt;preg_match_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/&amp;lt;loc&amp;gt;([^&amp;lt;]+)&amp;lt;\/loc&amp;gt;/'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$xml&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$m&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="nv"&gt;$existing&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;array_flip&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$m&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="p"&gt;[]);&lt;/span&gt;

&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;?xml version="1.0" encoding="UTF-8"?&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9"&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$posts&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nv"&gt;$url&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_permalink&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="k"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$existing&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="p"&gt;]))&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$mod&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;get_the_modified_date&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Y-m-d'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;$post&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"&amp;lt;url&amp;gt;&amp;lt;loc&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$url&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/loc&amp;gt;&amp;lt;lastmod&amp;gt;&lt;/span&gt;&lt;span class="si"&gt;{&lt;/span&gt;&lt;span class="nv"&gt;$mod&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;/lastmod&amp;gt;&amp;lt;/url&amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s1"&gt;'&amp;lt;/urlset&amp;gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then I submitted &lt;code&gt;ww-sitemap.php&lt;/code&gt; in Google Search Console alongside the existing &lt;code&gt;sitemap_index.xml&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Result
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Before: 49 URLs in sitemap, 16 posts invisible to Google&lt;/li&gt;
&lt;li&gt;After: All 65 posts discoverable&lt;/li&gt;
&lt;li&gt;Bing picked up the missing pages within 48 hours via IndexNow&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Lessons Learned
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Always verify your sitemap contains all your pages — don't assume the plugin handles it&lt;/li&gt;
&lt;li&gt;Dynamic PHP sitemaps are a valid fallback when plugin settings aren't accessible&lt;/li&gt;
&lt;li&gt;Submit supplementary sitemaps in GSC — you can have multiple&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Site: &lt;a href="https://watchwalls.pro" rel="noopener noreferrer"&gt;watchwalls.pro&lt;/a&gt; — an Apple Watch wallpaper resource where I discovered this problem.&lt;/p&gt;

</description>
      <category>wordpress</category>
      <category>seo</category>
      <category>php</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
