<?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: Smart Solutions</title>
    <description>The latest articles on DEV Community by Smart Solutions (@smartsolutionsapps).</description>
    <link>https://dev.to/smartsolutionsapps</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%2F4202544%2F4ae3b39a-44ba-4ade-8833-2634f40b881e.jpg</url>
      <title>DEV Community: Smart Solutions</title>
      <link>https://dev.to/smartsolutionsapps</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/smartsolutionsapps"/>
    <language>en</language>
    <item>
      <title>Your image sitemap is already a social media feed</title>
      <dc:creator>Smart Solutions</dc:creator>
      <pubDate>Fri, 23 Oct 2026 13:07:07 +0000</pubDate>
      <link>https://dev.to/smartsolutionsapps/your-image-sitemap-is-already-a-social-media-feed-2n4p</link>
      <guid>https://dev.to/smartsolutionsapps/your-image-sitemap-is-already-a-social-media-feed-2n4p</guid>
      <description>&lt;p&gt;Every image sitemap I have ever written was a thing I produced &lt;em&gt;for crawlers&lt;/em&gt; and then never read again. It turns out mine had been quietly maintaining a publishing queue for months, and I only noticed when I went to build one.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing I was about to build
&lt;/h2&gt;

&lt;p&gt;I wanted a small job that posts one illustrated page a day to Bluesky and Mastodon: the artwork, a line of the story, and a link back to the book.&lt;/p&gt;

&lt;p&gt;The plan was the obvious one — query the database for books, join the illustrations, pull a caption from somewhere, render a queue. A day of work, a new table, another thing to keep in sync with the site.&lt;/p&gt;

&lt;h2&gt;
  
  
  The thing that already existed
&lt;/h2&gt;

&lt;p&gt;Then I actually opened the sitemap we publish for Google Images:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;loc&amp;gt;&lt;/span&gt;https://thewonderbooks.com/app/comics/book/astral_echoes_scars_of_tomorrow&lt;span class="nt"&gt;&amp;lt;/loc&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;image:image&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;image:loc&amp;gt;&lt;/span&gt;.../covers/astral_echoes_cover_large.webp&lt;span class="nt"&gt;&amp;lt;/image:loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;image:title&amp;gt;&lt;/span&gt;Astral Echoes: Scars of Tomorrow — book cover&lt;span class="nt"&gt;&amp;lt;/image:title&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/image:image&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;image:image&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;image:loc&amp;gt;&lt;/span&gt;.../illustrations/astral_echoes_page_01.webp&lt;span class="nt"&gt;&amp;lt;/image:loc&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;image:caption&amp;gt;&lt;/span&gt;The Painted Desert shimmered under twin suns, its sands
      swirling with colors unknown on Earth.&lt;span class="nt"&gt;&amp;lt;/image:caption&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/image:image&amp;gt;&lt;/span&gt;
  ...
&lt;span class="nt"&gt;&amp;lt;/url&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Per book, in one file, already public, already correct:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the canonical reader URL&lt;/li&gt;
&lt;li&gt;the cover&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;every&lt;/strong&gt; page illustration&lt;/li&gt;
&lt;li&gt;and &lt;code&gt;image:caption&lt;/code&gt; — which, because of how the sitemap is generated, is &lt;em&gt;the sentence printed on that page of the book&lt;/em&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That is a post. Image, copy, destination. The caption is better than anything I would have written for a social post, because it is the actual prose a reader sees.&lt;/p&gt;

&lt;p&gt;So the "pipeline" became a fetch and a parse:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;xml&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;SITE&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;/sitemaps/library-en.xml`&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;r&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;r&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;text&lt;/span&gt;&lt;span class="p"&gt;());&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;xml&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;&amp;lt;url&amp;gt;&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;slice&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="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;parseUrlBlock&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;filter&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;Boolean&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;2,036 book pages with artwork in English, and the same again in twelve more languages. No new table, no second source of truth, and it cannot drift from the site — if a book is not published, it is not in the sitemap, so it cannot be posted.&lt;/p&gt;

&lt;h2&gt;
  
  
  Three things that bit me anyway
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. The sitemap is XML, so the URLs are escaped.&lt;/strong&gt; A storage URL arrived as &lt;code&gt;?alt=media&amp;amp;amp;token=…&lt;/code&gt; and answered 403. I was unescaping captions and not hrefs. I found it by &lt;code&gt;HEAD&lt;/code&gt;-ing every queued URL before posting — 24 checks, one bad — rather than by trusting the exit code.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. A "cover" is not always where you think.&lt;/strong&gt; Most covers lived under &lt;code&gt;/covers/&lt;/code&gt;, so I keyed on the path. Some books use their page-1 illustration as the cover, marked only by its &lt;em&gt;caption&lt;/em&gt; reading &lt;code&gt;— book cover —&lt;/code&gt;. Those posted as if they were inside pages, using "Title — book cover — Library" as the story line. Read the caption first, the path second.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Link cards and image embeds are not the same post.&lt;/strong&gt; On Bluesky I attached the artwork as an external card thumbnail &lt;em&gt;and&lt;/em&gt; left the URL in the text. The card already shows the title, the description and the domain, so the raw URL wrapped mid-slug across two lines underneath a card that said the same thing. The card is clickable on its own. Delete the URL from the text.&lt;/p&gt;

&lt;p&gt;All three were found by looking at the published post, not by reading logs. The logs were green for every one of them.&lt;/p&gt;

&lt;h2&gt;
  
  
  The general version
&lt;/h2&gt;

&lt;p&gt;If you publish a sitemap with &lt;code&gt;image:&lt;/code&gt; extensions, you already have a structured, deduplicated, always-current feed of every piece of media you own, with human-written captions attached, keyed to canonical URLs. You built it for Googlebot. It works just as well for anything else that needs "an image, a line, and a link".&lt;/p&gt;

&lt;p&gt;Worth opening yours before you build the thing you think you need.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;I build &lt;a href="https://thewonderbooks.com/" rel="noopener noreferrer"&gt;WonderBooks&lt;/a&gt; — twelve free illustrated libraries in thirteen languages. The sitemap above is the real one.&lt;/em&gt;&lt;/p&gt;

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