<?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: Rahul</title>
    <description>The latest articles on DEV Community by Rahul (@rahul_85ac39adcd5c87cfd93).</description>
    <link>https://dev.to/rahul_85ac39adcd5c87cfd93</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%2F4048697%2Ff441012b-3f65-44d0-b4ba-41a626512312.png</url>
      <title>DEV Community: Rahul</title>
      <link>https://dev.to/rahul_85ac39adcd5c87cfd93</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rahul_85ac39adcd5c87cfd93"/>
    <language>en</language>
    <item>
      <title>I made an invoice PDF API that doesn't need a headless browser</title>
      <dc:creator>Rahul</dc:creator>
      <pubDate>Mon, 27 Jul 2026 06:17:32 +0000</pubDate>
      <link>https://dev.to/rahul_85ac39adcd5c87cfd93/i-made-an-invoice-pdf-api-that-doesnt-need-a-headless-browser-4djg</link>
      <guid>https://dev.to/rahul_85ac39adcd5c87cfd93/i-made-an-invoice-pdf-api-that-doesnt-need-a-headless-browser-4djg</guid>
      <description>&lt;h2&gt;
  
  
  Generating a PDF shouldn't require a headless browser
&lt;/h2&gt;

&lt;p&gt;Every time I needed to generate an invoice or receipt PDF, the options were:&lt;br&gt;
wrestle a low-level PDF library, fight a templating engine, or spin up headless&lt;br&gt;
Chromium (slow, heavy, breaks on fonts, painful to host). For a &lt;em&gt;document&lt;/em&gt;, that&lt;br&gt;
felt absurd.&lt;/p&gt;

&lt;p&gt;So I built &lt;a href="https://invoicepdf-app.azurewebsites.net" rel="noopener noreferrer"&gt;InvoicePDF&lt;/a&gt;: &lt;strong&gt;POST JSON, get a clean invoice PDF back.&lt;/strong&gt;&lt;br&gt;
That's the whole thing.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nt"&gt;-X&lt;/span&gt; POST https://invoicepdf-app.azurewebsites.net/invoice &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-H&lt;/span&gt; &lt;span class="s2"&gt;"Content-Type: application/json"&lt;/span&gt; &lt;span class="se"&gt;\&lt;/span&gt;
  &lt;span class="nt"&gt;-d&lt;/span&gt; &lt;span class="s1"&gt;'{
    "number": "INV-2026-001",
    "currency": "USD",
    "seller_name": "Your Company LLC",
    "buyer_name": "Acme Corp",
    "items": [
      { "description": "Consulting (hours)", "quantity": 8, "unit_price": 120 },
      { "description": "Software license", "quantity": 1, "unit_price": 299 }
    ],
    "tax_rate_percent": 10,
    "notes": "Thank you!"
  }'&lt;/span&gt; &lt;span class="nt"&gt;--output&lt;/span&gt; invoice.pdf
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  Why pure Python (no chromium)
&lt;/h2&gt;

&lt;p&gt;It's built on &lt;code&gt;fpdf2&lt;/code&gt; — a pure-Python PDF library — so there's &lt;strong&gt;no headless&lt;br&gt;
browser and no system dependencies.&lt;/strong&gt; That means it starts instantly, uses&lt;br&gt;
almost no memory, and deploys on a free tier like a static app. For structured&lt;br&gt;
documents (invoices, receipts, statements), you don't need a browser; you need&lt;br&gt;
correct layout and correct math.&lt;/p&gt;

&lt;h2&gt;
  
  
  The money math is exact
&lt;/h2&gt;

&lt;p&gt;Financial documents can't have floating-point drift. InvoicePDF does all money&lt;br&gt;
as &lt;strong&gt;integer minor units&lt;/strong&gt; (cents/paise) internally, so &lt;code&gt;$27.00 subtotal + 10%&lt;br&gt;
tax&lt;/code&gt; is exactly &lt;code&gt;$29.70&lt;/code&gt; — never &lt;code&gt;$29.700000001&lt;/code&gt;. It handles multiple currencies&lt;br&gt;
(including zero-decimal ones like JPY), fractional quantities (e.g. hours), tax,&lt;br&gt;
notes, and due dates.&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it / use it
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Live playground&lt;/strong&gt; (edit JSON, get a PDF): &lt;a href="https://invoicepdf-app.azurewebsites.net" rel="noopener noreferrer"&gt;https://invoicepdf-app.azurewebsites.net&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sample PDF&lt;/strong&gt;: &lt;a href="https://invoicepdf-app.azurewebsites.net/sample" rel="noopener noreferrer"&gt;https://invoicepdf-app.azurewebsites.net/sample&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Open source (MIT)&lt;/strong&gt;: &lt;a href="https://github.com/rahulatrkm/invoicepdf" rel="noopener noreferrer"&gt;https://github.com/rahulatrkm/invoicepdf&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Free tier is 100 invoices/mo, no signup. If you generate a lot, there's a cheap&lt;br&gt;
paid tier.&lt;/p&gt;

&lt;p&gt;What would make this actually useful in your stack — logo/branding, a hosted&lt;br&gt;
template editor, webhooks? Genuinely curious — feedback welcome.&lt;/p&gt;

</description>
      <category>python</category>
      <category>webdev</category>
      <category>api</category>
      <category>showdev</category>
    </item>
    <item>
      <title>The robots.txt mistake that hides your whole site from Google</title>
      <dc:creator>Rahul</dc:creator>
      <pubDate>Mon, 27 Jul 2026 05:11:05 +0000</pubDate>
      <link>https://dev.to/rahul_85ac39adcd5c87cfd93/the-robotstxt-mistake-that-hides-your-whole-site-from-google-20al</link>
      <guid>https://dev.to/rahul_85ac39adcd5c87cfd93/the-robotstxt-mistake-that-hides-your-whole-site-from-google-20al</guid>
      <description>&lt;h2&gt;
  
  
  One line can hide your whole site from Google
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;Disallow: /&lt;/code&gt; in your &lt;code&gt;robots.txt&lt;/code&gt; tells every crawler to ignore your entire&lt;br&gt;
site. It's shockingly common — usually left over from a staging config that got&lt;br&gt;
copied to production. And nothing tells you: your pages just quietly stop&lt;br&gt;
ranking.&lt;/p&gt;

&lt;p&gt;I kept getting bitten by &lt;code&gt;robots.txt&lt;/code&gt; and &lt;code&gt;sitemap.xml&lt;/code&gt; issues, so I added free&lt;br&gt;
checks for them to &lt;a href="https://ogcheck-app.azurewebsites.net" rel="noopener noreferrer"&gt;OGCheck&lt;/a&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  Check your robots.txt in one request
&lt;/h2&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://ogcheck-app.azurewebsites.net/robots?url=https://your-site.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;It confirms the file is &lt;strong&gt;reachable&lt;/strong&gt;, &lt;strong&gt;parseable&lt;/strong&gt;, flags a &lt;strong&gt;site-wide block&lt;/strong&gt;,&lt;br&gt;
and tells you whether it points at your &lt;strong&gt;sitemap&lt;/strong&gt;.&lt;/p&gt;
&lt;h2&gt;
  
  
  The robots.txt mistakes that quietly cost you traffic
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;&lt;code&gt;Disallow: /&lt;/code&gt;&lt;/strong&gt; — blocks everything. The classic staging-to-prod accident.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Missing file&lt;/strong&gt; — crawlers assume everything is allowed, which may expose
pages you didn't mean to (and you lose the chance to point at your sitemap).&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No &lt;code&gt;Sitemap:&lt;/code&gt; line&lt;/strong&gt; — search engines crawl your site less efficiently.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Blocking your CSS/JS&lt;/strong&gt; — Google renders pages; blocking assets can hurt how
it sees them.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  While you're at it, check your sitemap too
&lt;/h2&gt;

&lt;p&gt;A broken or empty &lt;code&gt;sitemap.xml&lt;/code&gt; hurts crawl efficiency the same quiet way:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="s2"&gt;"https://ogcheck-app.azurewebsites.net/sitemap?url=https://your-site.com"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Both checks are free, zero-dependency (pure Python stdlib), and open source:&lt;br&gt;
&lt;a href="https://github.com/rahulatrkm/ogcheck" rel="noopener noreferrer"&gt;https://github.com/rahulatrkm/ogcheck&lt;/a&gt;. There's also a social-preview check&lt;br&gt;
(&lt;code&gt;/check?url=…&lt;/code&gt;) that confirms your &lt;code&gt;og:image&lt;/code&gt; actually loads.&lt;/p&gt;

&lt;p&gt;Feedback welcome — what else silently breaks your site's visibility that a&lt;br&gt;
one-request check could catch?&lt;/p&gt;

</description>
      <category>seo</category>
      <category>webdev</category>
      <category>python</category>
      <category>beginners</category>
    </item>
    <item>
      <title>Your blog's link preview is probably broken — here's a 1-line CI check</title>
      <dc:creator>Rahul</dc:creator>
      <pubDate>Mon, 27 Jul 2026 04:54:24 +0000</pubDate>
      <link>https://dev.to/rahul_85ac39adcd5c87cfd93/your-blogs-link-preview-is-probably-broken-heres-a-1-line-ci-check-2mab</link>
      <guid>https://dev.to/rahul_85ac39adcd5c87cfd93/your-blogs-link-preview-is-probably-broken-heres-a-1-line-ci-check-2mab</guid>
      <description>&lt;h2&gt;
  
  
  The silent bug that quietly kills your click-through
&lt;/h2&gt;

&lt;p&gt;You add &lt;code&gt;&amp;lt;meta property="og:image" content="..."&amp;gt;&lt;/code&gt;, the preview looks fine when&lt;br&gt;
you test it, you ship. Weeks later the image gets moved, the CDN path changes, or&lt;br&gt;
it was a relative URL all along — and now every share is a blank card. Your&lt;br&gt;
click-through quietly drops and &lt;strong&gt;nothing alerts you.&lt;/strong&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Catch it in one request (or in CI)
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://ogcheck-app.azurewebsites.net" rel="noopener noreferrer"&gt;OGCheck&lt;/a&gt; to catch exactly this. It parses your Open Graph +&lt;br&gt;
Twitter Card tags, scores them, and — the key part most validators skip —&lt;br&gt;
&lt;strong&gt;actually requests the &lt;code&gt;og:image&lt;/code&gt; to confirm it returns HTTP 200.&lt;/strong&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;python &lt;span class="nt"&gt;-m&lt;/span&gt; ogcheck https://your-site.com/blog/post
&lt;span class="c"&gt;# exits non-zero if og:image 404s or required tags are missing -&amp;gt; perfect for CI&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There's a JSON API and a GitHub Action too:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="pi"&gt;-&lt;/span&gt; &lt;span class="na"&gt;uses&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;rahulatrkm/ogcheck@v1&lt;/span&gt;
  &lt;span class="na"&gt;with&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;https://your-site.com&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  The 5 things that actually break previews
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;The image URL 404s (most common)&lt;/li&gt;
&lt;li&gt;A relative URL instead of an absolute one&lt;/li&gt;
&lt;li&gt;A cached old preview on the platform (re-scrape to bust it)&lt;/li&gt;
&lt;li&gt;Wrong dimensions or file type (use PNG/JPG at 1200×630)&lt;/li&gt;
&lt;li&gt;Crawlers blocked by robots.txt or auth&lt;/li&gt;
&lt;/ol&gt;

&lt;h2&gt;
  
  
  It's a small "site health" suite now
&lt;/h2&gt;

&lt;p&gt;Same free API also checks the other things that silently break how your site&lt;br&gt;
shows up:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;GET /check?url=…&lt;/code&gt; — social preview (Open Graph + og:image loads)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /robots?url=…&lt;/code&gt; — robots.txt (catches an accidental site-wide &lt;code&gt;Disallow: /&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;GET /sitemap?url=…&lt;/code&gt; — sitemap.xml (valid XML, reachable, lists URLs)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;It's free, zero-dependency (pure Python stdlib), and open source:&lt;br&gt;
&lt;a href="https://github.com/rahulatrkm/ogcheck" rel="noopener noreferrer"&gt;https://github.com/rahulatrkm/ogcheck&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you monitor a lot of pages, I'm thinking about a paid "watch these URLs and&lt;br&gt;
alert me when a preview breaks" tier — would that be useful? Honest feedback&lt;br&gt;
very welcome, especially on false positives.&lt;/p&gt;

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