<?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: WaterShow</title>
    <description>The latest articles on DEV Community by WaterShow (@watershow).</description>
    <link>https://dev.to/watershow</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%2F4206643%2F2c1b57c7-fecb-4907-99a7-0b67c18b3946.png</url>
      <title>DEV Community: WaterShow</title>
      <link>https://dev.to/watershow</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/watershow"/>
    <language>en</language>
    <item>
      <title>Why Google and ChatGPT can't see your Lovable app (and how to fix it)</title>
      <dc:creator>WaterShow</dc:creator>
      <pubDate>Mon, 26 Oct 2026 20:59:22 +0000</pubDate>
      <link>https://dev.to/watershow/why-google-and-chatgpt-cant-see-your-lovable-app-and-how-to-fix-it-3en</link>
      <guid>https://dev.to/watershow/why-google-and-chatgpt-cant-see-your-lovable-app-and-how-to-fix-it-3en</guid>
      <description>&lt;p&gt;You built the app in Lovable, Bolt or v0, it works, people like it. Then you search for it on Google and get nothing useful, and when you ask ChatGPT about your product it has never heard of it.&lt;/p&gt;

&lt;p&gt;Most of the time the app is fine. The problem is what search engines and AI assistants receive when they open your link.&lt;/p&gt;

&lt;h2&gt;
  
  
  What a crawler actually downloads
&lt;/h2&gt;

&lt;p&gt;Apps from AI builders are usually single-page React apps. When anyone opens the link, the server sends a tiny HTML file that looks roughly like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight html"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;div&lt;/span&gt; &lt;span class="na"&gt;id=&lt;/span&gt;&lt;span class="s"&gt;"root"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/div&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;script &lt;/span&gt;&lt;span class="na"&gt;type=&lt;/span&gt;&lt;span class="s"&gt;"module"&lt;/span&gt; &lt;span class="na"&gt;src=&lt;/span&gt;&lt;span class="s"&gt;"/assets/index-a1b2c3.js"&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Your headings, prices, features and contact details are not in that file. They appear only after the browser downloads and runs the JavaScript. People never notice, because their browser does it in a second.&lt;/p&gt;

&lt;h2&gt;
  
  
  Who runs JavaScript and who doesn't
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;Google&lt;/strong&gt; can run JavaScript, but it does it in a second pass that can come days later, and pages with heavy scripts sometimes get indexed with missing text or not at all.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;AI assistants&lt;/strong&gt; are worse off. The crawlers behind ChatGPT, Claude and Perplexity mostly read the HTML and do not run JavaScript. In &lt;a href="https://vercel.com/blog/the-rise-of-the-ai-crawler" rel="noopener noreferrer"&gt;Vercel's analysis of AI crawler traffic&lt;/a&gt;, none of the major AI crawlers rendered JavaScript. For them your app is an empty &lt;code&gt;div&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So the same page that looks great to a visitor can be invisible to the tools people now use to find products.&lt;/p&gt;

&lt;h2&gt;
  
  
  Check your app in 30 seconds
&lt;/h2&gt;

&lt;p&gt;The quickest way: paste your link into the free &lt;a href="https://dev.to/tools/visibility-check"&gt;visibility check&lt;/a&gt;. It shows how many words of your content are in the HTML, plus the title, description, link preview, sitemap, robots.txt, llms.txt and mobile speed, each with what to fix.&lt;/p&gt;

&lt;p&gt;If you prefer to do it by hand, open your site and press &lt;code&gt;Ctrl+U&lt;/code&gt; (or &lt;code&gt;Cmd+Option+U&lt;/code&gt; on a Mac) to view the page source. Search for a sentence that is visible on the page. If you cannot find it in the source, crawlers cannot find it either.&lt;/p&gt;

&lt;h2&gt;
  
  
  Five fixes, from easiest to most thorough
&lt;/h2&gt;

&lt;p&gt;&lt;strong&gt;1. Put the basics in index.html.&lt;/strong&gt; Even a single-page app has one real HTML file. Give it a proper &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt;, a meta description, Open Graph tags for link previews and a canonical link. In Lovable you can ask it to edit &lt;code&gt;index.html&lt;/code&gt;, or change it in the code on GitHub. This alone fixes how your link looks in search results and chats.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Add robots.txt, sitemap.xml and llms.txt.&lt;/strong&gt; Put them in the &lt;code&gt;public&lt;/code&gt; folder so they are served from the root of your domain. The sitemap lists your pages, robots.txt points crawlers to it, and llms.txt is a short plain-text summary of what your site offers, written for AI assistants.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Add structured data.&lt;/strong&gt; A small JSON-LD block in &lt;code&gt;index.html&lt;/code&gt; that says who you are, what you sell and where you are. Google and AI assistants use it to describe your business without guessing.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Prerender your public pages.&lt;/strong&gt; This is the fix that actually puts your text into the HTML. A prerender step runs your app at build time and saves the finished HTML for each public route (home, pricing, features, blog). Visitors still get the full app, but crawlers receive real content. For a Vite app like the ones Lovable and Bolt generate, this is usually a plugin plus a list of routes to render.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Move the marketing pages to a framework that renders on the server.&lt;/strong&gt; If content and search traffic matter a lot, keep the logged-in app where it is and build the public pages with Next.js or Astro, which send full HTML by default. It is more work, but it is the most robust option.&lt;/p&gt;

&lt;p&gt;For most apps, steps 1 to 4 are enough and take a day or two.&lt;/p&gt;

&lt;h2&gt;
  
  
  What I usually find
&lt;/h2&gt;

&lt;p&gt;When I check apps built with AI tools, the pattern is almost always the same: a generic title like "Vite + React", no description, no link preview image, no sitemap, and fewer than twenty words of real content in the HTML. Each piece is small, but together they make the product invisible outside of direct links.&lt;/p&gt;

&lt;p&gt;If you want it done for you, I fix exactly this: prerendering, meta tags, link previews, sitemap, robots.txt, structured data and llms.txt, with a fixed quote first. Run the &lt;a href="https://dev.to/tools/visibility-check"&gt;free check&lt;/a&gt; and send me the report.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Can Google index a Lovable app at all?
&lt;/h3&gt;

&lt;p&gt;Yes, but slowly and not always completely. Google renders JavaScript in a second pass, so pages can sit unindexed for days or get indexed with missing text. Putting real text into the HTML with prerendering removes the guesswork.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why does ChatGPT not know about my product?
&lt;/h3&gt;

&lt;p&gt;The crawlers that feed ChatGPT, Claude and Perplexity mostly read only the HTML and do not run JavaScript. If your content appears only after scripts run, they see an empty page and have nothing to quote.&lt;/p&gt;

&lt;h3&gt;
  
  
  Do I need to rebuild my app to fix this?
&lt;/h3&gt;

&lt;p&gt;Usually not. Fixing index.html, adding a sitemap, robots.txt, llms.txt and structured data, and prerendering the public pages keeps your app as it is. Moving marketing pages to Next.js or Astro is only worth it when search traffic really matters.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://watershowdigital.com/blog/why-chatgpt-cant-see-your-lovable-app" rel="noopener noreferrer"&gt;watershowdigital.com/blog/why-chatgpt-cant-see-your-lovable-app&lt;/a&gt;.&lt;/em&gt; Need a hand with your app or automation? &lt;a href="https://watershowdigital.com/build" rel="noopener noreferrer"&gt;WaterShow Digital&lt;/a&gt; fixes and builds it, fixed quote first.&lt;/p&gt;

</description>
      <category>lovable</category>
      <category>seo</category>
      <category>webdev</category>
      <category>ai</category>
    </item>
    <item>
      <title>How to get Reddit data in 2026 now that the API is closed</title>
      <dc:creator>WaterShow</dc:creator>
      <pubDate>Mon, 26 Oct 2026 02:07:47 +0000</pubDate>
      <link>https://dev.to/watershow/how-to-get-reddit-data-in-2026-now-that-the-api-is-closed-5697</link>
      <guid>https://dev.to/watershow/how-to-get-reddit-data-in-2026-now-that-the-api-is-closed-5697</guid>
      <description>&lt;p&gt;If you tried to create a Reddit app recently, you hit a wall. Since November 2025 Reddit no longer hands out API keys on request: every new app needs manual approval under the Responsible Builder Policy, and personal or small commercial projects are often turned down or never hear back. Even automation tools like Make and Pipedream now ask you for your own approved Reddit app before they connect.&lt;/p&gt;

&lt;p&gt;So what do you do if you just need posts and comments for research, lead generation or monitoring? Here are the options that still work, from simplest to most capable.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. RSS feeds, for light monitoring
&lt;/h2&gt;

&lt;p&gt;Almost every Reddit listing has an RSS version. Add &lt;code&gt;.rss&lt;/code&gt; to the URL:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;https://www.reddit.com/r/SaaS/new/.rss
https://www.reddit.com/search.rss?q=looking+for+a+crm&amp;amp;sort=new
https://www.reddit.com/r/SaaS/comments/abc123/.rss
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You get titles, full post text, authors and dates, up to 100 items per request. Good enough to watch a few subreddits or keywords.&lt;/p&gt;

&lt;p&gt;The limits: no scores, no comment counts, and Reddit rate limits RSS hard. If you poll more than a few times a minute from one IP you start getting &lt;code&gt;429 Too Many Requests&lt;/code&gt;. Combine several subreddits into one feed (&lt;code&gt;/r/a+b+c/new/.rss&lt;/code&gt;) to make fewer requests.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Apply for API access anyway
&lt;/h2&gt;

&lt;p&gt;If you need to post or vote, the API is the only legitimate way, so it is worth applying. Use the support request form on reddithelp.com, describe one concrete use case, the volume, and how you handle data. Be honest about commercial use. Expect anything from a week to no answer at all, so do not build a business that depends on it.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. A scraper that reads public pages
&lt;/h2&gt;

&lt;p&gt;For anything bigger than a few feeds, you want a tool that reads Reddit's public pages for you, handles rate limits and gives you clean data. I built &lt;a href="https://apify.com/watershowdigital/reddit-lead-finder" rel="noopener noreferrer"&gt;Reddit Scraper &amp;amp; AI Lead Finder&lt;/a&gt; for this. It needs no API key and no Reddit login:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;search posts by keyword, sitewide or inside subreddits&lt;/li&gt;
&lt;li&gt;pull new, hot, top or rising posts from any subreddit&lt;/li&gt;
&lt;li&gt;get posts from a user profile, or comments from a post URL&lt;/li&gt;
&lt;li&gt;scores, comment counts, upvote ratio and full text, ready for CSV or JSON
&lt;/li&gt;
&lt;/ul&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;"searchQueries"&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="s2"&gt;"looking for a crm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"alternative to hubspot"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"subreddits"&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="s2"&gt;"SaaS"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"startups"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"sort"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"new"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"timeRange"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"week"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxPostsPerSource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&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;It costs $1 per 1,000 posts. If you add a short description of what you sell, its optional AI mode scores each post for buying intent and drafts a reply, which turns it into a lead finder rather than a plain scraper.&lt;/p&gt;

&lt;h2&gt;
  
  
  Which one to pick
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Watching a few keywords for yourself:&lt;/strong&gt; RSS feeds and a small script.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Research, dashboards, lead lists, anything over a few hundred posts a day:&lt;/strong&gt; a managed scraper.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Posting, voting or messaging:&lt;/strong&gt; only the official API. Do not automate those any other way, Reddit bans accounts for it.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Play fair
&lt;/h2&gt;

&lt;p&gt;Whatever you use, stick to public data, keep request rates reasonable, and do not collect personal information you do not need. Reddit is a community first. Tools that read it to find people who need help are fine. Tools that spam it get everyone blocked.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How can I read Reddit posts without an API key?
&lt;/h3&gt;

&lt;p&gt;You can use RSS feeds for light monitoring by adding .rss to Reddit URLs. For pulling larger amounts of data for research or dashboards, you can use a managed scraper. Scrapers read public pages without needing an API key or a Reddit login.&lt;/p&gt;

&lt;h3&gt;
  
  
  What data is included in a Reddit RSS feed?
&lt;/h3&gt;

&lt;p&gt;A Reddit RSS feed provides the titles, full post text, authors and dates for up to 100 items. It does not include post scores or comment counts. You also have to be careful with rate limits to avoid getting error messages.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can I still automate posting and voting on Reddit?
&lt;/h3&gt;

&lt;p&gt;Only through the official API. Since November 2025 every new Reddit app needs manual approval under the Responsible Builder Policy, and small projects are often turned down. Automating posting or voting any other way gets accounts banned.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://watershowdigital.com/blog/reddit-data-without-api-2026" rel="noopener noreferrer"&gt;watershowdigital.com/blog/reddit-data-without-api-2026&lt;/a&gt;.&lt;/em&gt; Need a hand with your app or automation? &lt;a href="https://watershowdigital.com/build" rel="noopener noreferrer"&gt;WaterShow Digital&lt;/a&gt; fixes and builds it, fixed quote first.&lt;/p&gt;

</description>
      <category>reddit</category>
      <category>scraping</category>
      <category>api</category>
      <category>python</category>
    </item>
    <item>
      <title>Lovable app works in preview but breaks after deploy? Seven fixes</title>
      <dc:creator>WaterShow</dc:creator>
      <pubDate>Mon, 26 Oct 2026 02:07:46 +0000</pubDate>
      <link>https://dev.to/watershow/lovable-app-works-in-preview-but-breaks-after-deploy-seven-fixes-5211</link>
      <guid>https://dev.to/watershow/lovable-app-works-in-preview-but-breaks-after-deploy-seven-fixes-5211</guid>
      <description>&lt;p&gt;Everything works in the Lovable preview. You deploy it to your own domain on Vercel or Netlify, and suddenly login loops, pages go blank or the data never shows up.&lt;/p&gt;

&lt;p&gt;The app is almost never "broken". Something that the preview handled for you is missing in production. Here are the seven causes I see most often, in the order I check them.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Supabase still redirects to localhost or the preview URL
&lt;/h2&gt;

&lt;p&gt;Symptom: you log in, and you land on &lt;code&gt;localhost:3000&lt;/code&gt; or the old preview link, or you end up back on the login page.&lt;/p&gt;

&lt;p&gt;Fix: in Supabase go to &lt;strong&gt;Authentication → URL Configuration&lt;/strong&gt;.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Site URL:&lt;/strong&gt; your real domain, for example &lt;code&gt;https://myapp.com&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Redirect URLs:&lt;/strong&gt; add &lt;code&gt;https://myapp.com/**&lt;/code&gt; (and your Vercel preview domain if you use it)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;If you use Google or GitHub login, the provider's own console needs the Supabase callback URL too: &lt;code&gt;https://&amp;lt;project&amp;gt;.supabase.co/auth/v1/callback&lt;/code&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  2. Environment variables are missing on the host
&lt;/h2&gt;

&lt;p&gt;Symptom: blank page, or errors like &lt;code&gt;supabaseUrl is required&lt;/code&gt; in the browser console.&lt;/p&gt;

&lt;p&gt;Lovable keeps your keys in the project. Vercel and Netlify do not know them. Add them in the host's settings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight conf"&gt;&lt;code&gt;&lt;span class="n"&gt;VITE_SUPABASE_URL&lt;/span&gt;=&lt;span class="n"&gt;https&lt;/span&gt;://&lt;span class="n"&gt;xxxx&lt;/span&gt;.&lt;span class="n"&gt;supabase&lt;/span&gt;.&lt;span class="n"&gt;co&lt;/span&gt;
&lt;span class="n"&gt;VITE_SUPABASE_PUBLISHABLE_KEY&lt;/span&gt;=...
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then &lt;strong&gt;redeploy&lt;/strong&gt;. Variables are baked in at build time, so changing them without a new build does nothing.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Refreshing a page gives a 404
&lt;/h2&gt;

&lt;p&gt;Symptom: the home page works, but refreshing &lt;code&gt;/dashboard&lt;/code&gt; or opening it from a link shows "404 Not Found".&lt;/p&gt;

&lt;p&gt;Lovable apps are single page apps: there is only one real &lt;code&gt;index.html&lt;/code&gt;. Tell the host to send every route to it.&lt;/p&gt;

&lt;p&gt;Vercel, &lt;code&gt;vercel.json&lt;/code&gt; in the project root:&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;"rewrites"&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;"source"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&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;"destination"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"/index.html"&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;Netlify, a file &lt;code&gt;public/_redirects&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;/*  /index.html  200
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  4. RLS blocks the data in production
&lt;/h2&gt;

&lt;p&gt;Symptom: the page loads but lists are empty, or saving fails with &lt;code&gt;new row violates row-level security policy&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In the preview you might have been testing as a different user, or with policies that changed since. Check that every table your app reads has a &lt;code&gt;select&lt;/code&gt; policy for logged in users and every table it writes has a matching &lt;code&gt;insert&lt;/code&gt; or &lt;code&gt;update&lt;/code&gt; policy. I wrote a separate guide on &lt;a href="https://dev.to/blog/supabase-rls-blocks-inserts"&gt;the six causes of RLS insert errors&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  5. The service role key ended up in the frontend
&lt;/h2&gt;

&lt;p&gt;Symptom: everything works, which is the dangerous part.&lt;/p&gt;

&lt;p&gt;If your code creates the Supabase client with the &lt;code&gt;service_role&lt;/code&gt; key, anyone can open the network tab, copy it and read or delete your whole database. Search your code for &lt;code&gt;service_role&lt;/code&gt;. In the browser only the publishable (anon) key belongs. Anything that needs full access moves to an Edge Function.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. Stripe works in test mode only
&lt;/h2&gt;

&lt;p&gt;Symptom: checkout opens, payment succeeds, but the user never gets access.&lt;/p&gt;

&lt;p&gt;Usually the webhook is still pointing at the test endpoint or uses the test signing secret. In Stripe switch to live mode, create the webhook for your production URL, and put the live &lt;code&gt;STRIPE_WEBHOOK_SECRET&lt;/code&gt; into your function's secrets.&lt;/p&gt;

&lt;h2&gt;
  
  
  7. Emails go nowhere
&lt;/h2&gt;

&lt;p&gt;Symptom: sign up works but the confirmation email never arrives.&lt;/p&gt;

&lt;p&gt;Supabase's built in email is rate limited and meant for testing. For real users, connect your own SMTP (Resend, Postmark, SendGrid) under &lt;strong&gt;Authentication → SMTP Settings&lt;/strong&gt;, and add the DNS records your provider asks for so emails do not land in spam.&lt;/p&gt;

&lt;h2&gt;
  
  
  Still stuck?
&lt;/h2&gt;

&lt;p&gt;Open the browser console (F12) and the network tab, reproduce the problem and read the first red error. Nine times out of ten it names the cause. If it does not, or you would rather not spend the weekend on it, &lt;a href="https://dev.to/#founders"&gt;this is the kind of fix I do&lt;/a&gt;: fixed price up front, usually done in 48 hours.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why do I get a 404 error when I refresh my Lovable app?
&lt;/h3&gt;

&lt;p&gt;This happens because Lovable apps are single page apps with only one real index.html file. To fix it, you need to tell your host to send every route to that file. You do this using a vercel.json file for Vercel or a public/_redirects file for Netlify.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why is my Supabase data not loading after I deploy?
&lt;/h3&gt;

&lt;p&gt;Your environment variables might be missing from your Vercel or Netlify settings. If you add them, you must redeploy your app since variables are baked in at build time. It is also possible that your row-level security policies are blocking the data.&lt;/p&gt;

&lt;h3&gt;
  
  
  Why am I redirected to localhost after logging in?
&lt;/h3&gt;

&lt;p&gt;This occurs when Supabase still redirects to your old preview link or localhost. Go to the URL Configuration under Authentication in Supabase to fix this. Update your Site URL to your real domain and add it to your Redirect URLs.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://watershowdigital.com/blog/lovable-app-breaks-after-deploy" rel="noopener noreferrer"&gt;watershowdigital.com/blog/lovable-app-breaks-after-deploy&lt;/a&gt;.&lt;/em&gt; Need a hand with your app or automation? &lt;a href="https://watershowdigital.com/build" rel="noopener noreferrer"&gt;WaterShow Digital&lt;/a&gt; fixes and builds it, fixed quote first.&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>ai</category>
      <category>deployment</category>
      <category>javascript</category>
    </item>
    <item>
      <title>How to see every Google ad your competitor runs (and what to steal from them)</title>
      <dc:creator>WaterShow</dc:creator>
      <pubDate>Mon, 26 Oct 2026 02:02:33 +0000</pubDate>
      <link>https://dev.to/watershow/how-to-see-every-google-ad-your-competitor-runs-and-what-to-steal-from-them-1fa8</link>
      <guid>https://dev.to/watershow/how-to-see-every-google-ad-your-competitor-runs-and-what-to-steal-from-them-1fa8</guid>
      <description>&lt;p&gt;Your competitor has been testing ads for months and paying for every lesson. You can see the results for free, because Google publishes every ad in the &lt;a href="https://adstransparency.google.com/" rel="noopener noreferrer"&gt;Ads Transparency Center&lt;/a&gt;: Search, YouTube and Display, with the dates each ad ran and the countries it was shown in.&lt;/p&gt;

&lt;p&gt;Most people never open it. Here is how to use it properly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The manual way, for one competitor
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Open &lt;a href="https://adstransparency.google.com/" rel="noopener noreferrer"&gt;adstransparency.google.com&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Type the competitor's domain, for example &lt;code&gt;notion.com&lt;/code&gt;, and pick the advertiser from the list. Big companies often have several verified advertiser accounts, one per country or product.&lt;/li&gt;
&lt;li&gt;Pick a country in the top bar. Without it you see ads from everywhere.&lt;/li&gt;
&lt;li&gt;Switch the format filter between text, image and video.&lt;/li&gt;
&lt;li&gt;Click an ad to see its versions, the countries it ran in and, for the EU, roughly how many times it was shown.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;This works fine for a quick look at one brand. It gets painful when you want 300 ads from five competitors in a spreadsheet, with the ad text you can actually search and sort.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fast way: pull everything into a table
&lt;/h2&gt;

&lt;p&gt;I built a small tool for this: &lt;a href="https://apify.com/watershowdigital/competitor-ad-spy" rel="noopener noreferrer"&gt;Google Ads Spy&lt;/a&gt; on Apify. You give it domains or advertiser names, it returns one row per ad:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;headline, description and call to action&lt;/li&gt;
&lt;li&gt;landing page URL (where the ad actually sends people)&lt;/li&gt;
&lt;li&gt;the YouTube link for video ads&lt;/li&gt;
&lt;li&gt;first and last date shown, and how many days the ad ran&lt;/li&gt;
&lt;li&gt;countries, and impressions where Google publishes them
&lt;/li&gt;
&lt;/ul&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;"domains"&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="s2"&gt;"notion.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"clickup.com"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"monday.com"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"region"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"US"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"format"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"video"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxAdsPerSource"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;100&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;It costs $1.50 per 1,000 ads with full details, so a full teardown of three competitors is well under a dollar. If you also have a Meta Ad Library API token, the same run pulls their Facebook and Instagram ads.&lt;/p&gt;

&lt;h2&gt;
  
  
  What to look for once you have the list
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. The ads that never stop
&lt;/h3&gt;

&lt;p&gt;Sort by how long each ad has been running. An ad that has run for 120 days is almost certainly profitable, nobody keeps paying for a loser that long. Those are the messages to study first.&lt;/p&gt;

&lt;h3&gt;
  
  
  2. The landing pages
&lt;/h3&gt;

&lt;p&gt;Group ads by landing page URL. You will usually find two or three pages that get most of the ads. That tells you which offer converts for them: a free trial, a demo, a template gallery, a comparison page against you.&lt;/p&gt;

&lt;h3&gt;
  
  
  3. The angle, not the wording
&lt;/h3&gt;

&lt;p&gt;Do not copy the headline. Write down the angle behind it: speed ("set up in 5 minutes"), price ("free for teams under 10"), pain ("stop chasing invoices"), social proof ("used by 50,000 teams"). Then test the same angle in your own words.&lt;/p&gt;

&lt;h3&gt;
  
  
  4. Where they spend
&lt;/h3&gt;

&lt;p&gt;The country list shows where they are pushing. If a competitor suddenly starts running ads in Germany, they are probably launching there. If they stopped in a market, it probably did not pay off.&lt;/p&gt;

&lt;h3&gt;
  
  
  5. Video hooks
&lt;/h3&gt;

&lt;p&gt;For YouTube ads, watch only the first five seconds of each. That is the hook they paid to test. Collect the ones that keep running and you have a swipe file of hooks that work in your niche.&lt;/p&gt;

&lt;h2&gt;
  
  
  A simple weekly routine
&lt;/h2&gt;

&lt;p&gt;Run the same input once a week with "only running ads" turned on and save the results. Compare with last week:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;new ads mean they are testing something&lt;/li&gt;
&lt;li&gt;ads that disappeared were probably losing&lt;/li&gt;
&lt;li&gt;a new landing page means a new offer&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Twenty minutes a week and you always know what your competitors are betting on, without paying for their mistakes.&lt;/p&gt;

&lt;h2&gt;
  
  
  Good to know
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Search ads are published as an image of the ad, so for those you get a screenshot rather than separate text fields.&lt;/li&gt;
&lt;li&gt;Impression numbers are only published for ads shown in the EU.&lt;/li&gt;
&lt;li&gt;This is public data Google shows on purpose, so anyone can check who advertises what. Use it to learn, not to clone someone's brand.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How much does it cost to download competitor Google ads?
&lt;/h3&gt;

&lt;p&gt;Using the Google Ads Spy tool on Apify costs $1.50 per 1,000 ads to pull the data into a table. Viewing the ads manually in the Google Ads Transparency Center is completely free.&lt;/p&gt;

&lt;h3&gt;
  
  
  Can you see how many impressions a competitor ad gets?
&lt;/h3&gt;

&lt;p&gt;Google only publishes impression numbers for ads shown in the European Union. For ads shown in other regions, you can see the active dates and countries but not the impression counts.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do you know if a competitor Google ad is profitable?
&lt;/h3&gt;

&lt;p&gt;You should look at how long the ad has been running. If an ad stays active for a long time, it is almost certainly profitable because advertisers do not keep paying for losing ads.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://watershowdigital.com/blog/see-competitor-google-ads" rel="noopener noreferrer"&gt;watershowdigital.com/blog/see-competitor-google-ads&lt;/a&gt;.&lt;/em&gt; Need a hand with your app or automation? &lt;a href="https://watershowdigital.com/build" rel="noopener noreferrer"&gt;WaterShow Digital&lt;/a&gt; fixes and builds it, fixed quote first.&lt;/p&gt;

</description>
      <category>googleads</category>
      <category>marketing</category>
      <category>scraping</category>
      <category>advertising</category>
    </item>
    <item>
      <title>How to find Substack newsletters to sponsor (with real subscriber counts)</title>
      <dc:creator>WaterShow</dc:creator>
      <pubDate>Mon, 26 Oct 2026 02:02:32 +0000</pubDate>
      <link>https://dev.to/watershow/how-to-find-substack-newsletters-to-sponsor-with-real-subscriber-counts-4a2n</link>
      <guid>https://dev.to/watershow/how-to-find-substack-newsletters-to-sponsor-with-real-subscriber-counts-4a2n</guid>
      <description>&lt;p&gt;Newsletter sponsorships are one of the few ad channels where people still read the ad. The catch is finding the right newsletters: ones your customers actually read, that are still active, and that are big enough to matter but small enough to afford.&lt;/p&gt;

&lt;p&gt;Substack hosts thousands of them. Here is how to build a shortlist.&lt;/p&gt;

&lt;h2&gt;
  
  
  What makes a newsletter worth sponsoring
&lt;/h2&gt;

&lt;p&gt;Before you search, decide what "good" means for you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Fit.&lt;/strong&gt; The topic matches your customer, not just your industry. A newsletter about "AI tools for lawyers" beats a general AI one if you sell to law firms.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Size.&lt;/strong&gt; Subscribers between 2,000 and 50,000 are usually the sweet spot for small budgets. Big names are expensive and often sold out.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Activity.&lt;/strong&gt; It posts every week or two. A newsletter that last posted three months ago is dead, whatever its subscriber count says.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A paid tier.&lt;/strong&gt; Writers with paying readers usually have a more engaged audience.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A real person you can reach.&lt;/strong&gt; You need an email, X or LinkedIn to pitch them.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  The manual way
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Go to &lt;a href="https://substack.com/" rel="noopener noreferrer"&gt;substack.com&lt;/a&gt; and search your topic.&lt;/li&gt;
&lt;li&gt;Open each newsletter, note the subscriber count if it is shown, and check the date of the last post.&lt;/li&gt;
&lt;li&gt;Look at the "About" page and the author profile for contact links.&lt;/li&gt;
&lt;li&gt;Put everything in a spreadsheet.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It works, but it is slow: 10 to 15 minutes per newsletter, and many hide the subscriber count on their own page.&lt;/p&gt;

&lt;h2&gt;
  
  
  The fast way
&lt;/h2&gt;

&lt;p&gt;I built &lt;a href="https://apify.com/watershowdigital/substack-newsletter-finder" rel="noopener noreferrer"&gt;Substack Newsletter Finder&lt;/a&gt; for exactly this. You give it keywords or categories and it returns a table:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;newsletter name and URL&lt;/li&gt;
&lt;li&gt;subscriber count and the author's follower count&lt;/li&gt;
&lt;li&gt;the author's X, LinkedIn, YouTube and website links&lt;/li&gt;
&lt;li&gt;last post date and how many posts in the last 30 days&lt;/li&gt;
&lt;li&gt;language and whether it has a paid plan
&lt;/li&gt;
&lt;/ul&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;"searchQueries"&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="s2"&gt;"b2b saas"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"startup marketing"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"minSubscribers"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;2000&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"activeWithinDays"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;30&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"language"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="s2"&gt;"en"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt;
  &lt;/span&gt;&lt;span class="nl"&gt;"maxResults"&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="mi"&gt;200&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;200 newsletters cost about $0.50. Filter by subscribers and activity, sort, and you have a shortlist in a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to pitch
&lt;/h2&gt;

&lt;p&gt;Keep the first email short and specific:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;one line on why their audience fits ("your readers are early stage founders, we make invoicing for them")&lt;/li&gt;
&lt;li&gt;what you want: one sponsored slot in an upcoming issue&lt;/li&gt;
&lt;li&gt;ask for their rate, or offer one if they do not have a media kit&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Start with three to five newsletters, not fifty. Run one slot each, track signups with a separate link or code per newsletter, and only rebook the ones that paid back.&lt;/p&gt;

&lt;h2&gt;
  
  
  Read before you buy
&lt;/h2&gt;

&lt;p&gt;Before paying, read the last five issues. Check that the writing is good, that ads are clearly marked and not stuffed in, and that readers reply or comment. Ten minutes of reading saves you from buying space in a newsletter nobody opens.&lt;/p&gt;

&lt;h2&gt;
  
  
  A shortcut for writers too
&lt;/h2&gt;

&lt;p&gt;If you run a newsletter yourself, the same list works in reverse: find newsletters of a similar size in your niche and propose a cross promotion. Both of you grow, nobody pays.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I find the subscriber count for a Substack newsletter?
&lt;/h3&gt;

&lt;p&gt;You can look for the subscriber count manually by opening each newsletter on Substack, though many writers hide this number. Alternatively, you can use the Substack Newsletter Finder tool to automatically pull subscriber counts for a list of newsletters.&lt;/p&gt;

&lt;h3&gt;
  
  
  What is a good subscriber size for a newsletter sponsorship?
&lt;/h3&gt;

&lt;p&gt;Subscribers between 2,000 and 50,000 are usually the best option for small budgets. Larger newsletters are often expensive and sold out.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I pitch a sponsorship to a Substack writer?
&lt;/h3&gt;

&lt;p&gt;Keep your first email short and explain why their audience fits your product. Tell them you want one sponsored slot in an upcoming issue. You should also ask for their rate or offer a price if they lack a media kit.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://watershowdigital.com/blog/find-substack-newsletters-to-sponsor" rel="noopener noreferrer"&gt;watershowdigital.com/blog/find-substack-newsletters-to-sponsor&lt;/a&gt;.&lt;/em&gt; Need a hand with your app or automation? &lt;a href="https://watershowdigital.com/build" rel="noopener noreferrer"&gt;WaterShow Digital&lt;/a&gt; fixes and builds it, fixed quote first.&lt;/p&gt;

</description>
      <category>substack</category>
      <category>marketing</category>
      <category>newsletter</category>
      <category>automation</category>
    </item>
    <item>
      <title>How to find customers on Reddit without spamming (or getting banned)</title>
      <dc:creator>WaterShow</dc:creator>
      <pubDate>Mon, 26 Oct 2026 01:57:10 +0000</pubDate>
      <link>https://dev.to/watershow/how-to-find-customers-on-reddit-without-spamming-or-getting-banned-2l4l</link>
      <guid>https://dev.to/watershow/how-to-find-customers-on-reddit-without-spamming-or-getting-banned-2l4l</guid>
      <description>&lt;p&gt;Every day somebody on Reddit writes "can anyone recommend a tool for..." or "I'm stuck with this, willing to pay someone to fix it". If you sell that thing, this is the warmest lead you will ever get: they asked first.&lt;/p&gt;

&lt;p&gt;The problem is finding those posts before 40 other people answer, and replying without looking like a spammer. Here is the approach that works for me.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 1: know what a buying post looks like
&lt;/h2&gt;

&lt;p&gt;Most posts in your niche are not leads. Discussions, launches and memes are noise. Buying intent sounds like this:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;"looking for a tool / app / service that..."&lt;/li&gt;
&lt;li&gt;"any alternative to X?" (they are unhappy with a competitor)&lt;/li&gt;
&lt;li&gt;"willing to pay", "budget is", "hiring", "need someone to"&lt;/li&gt;
&lt;li&gt;"how do I fix..." followed by a very concrete broken thing&lt;/li&gt;
&lt;li&gt;"we tried X and it didn't work"&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Write down 10 to 20 phrases like these for your product. They become your search queries.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 2: search the right places
&lt;/h2&gt;

&lt;p&gt;Reddit search is decent if you sort by new. Try queries like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"alternative to hubspot"
"looking for a crm"
"need help with supabase"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then list the subreddits where your customers hang out. Not the big general ones: the small, specific ones where people describe their actual problems. For a dev service that might be r/Supabase, r/nextjs, r/SaaS, r/indiehackers, r/forhire.&lt;/p&gt;

&lt;p&gt;Checking all of that by hand every day takes an hour. I built &lt;a href="https://apify.com/watershowdigital/reddit-lead-finder" rel="noopener noreferrer"&gt;Reddit Scraper &amp;amp; AI Lead Finder&lt;/a&gt; to do it: you give it search queries, subreddits and a short description of what you sell, and it returns the posts with an intent score, the pain point and a draft reply. You can schedule it every few hours and only look at posts that scored 7 or higher.&lt;/p&gt;

&lt;h2&gt;
  
  
  Step 3: answer like a person, not a brand
&lt;/h2&gt;

&lt;p&gt;This is where most people burn their account. Rules I follow:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Help first.&lt;/strong&gt; Give one concrete, useful tip for their exact problem. If your reply is useful without your product, you are doing it right.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Keep it short.&lt;/strong&gt; Two or three sentences. Nobody reads a wall of text from a stranger.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;No links in the first reply.&lt;/strong&gt; Links from new accounts get filtered or downvoted.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;One soft offer at the end.&lt;/strong&gt; Something like "I can help you set this up if you want, just message me." That is it.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Sound like yourself.&lt;/strong&gt; No "Great question!", no bullet points, no corporate tone.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;A good reply looks like this:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;sounds like your redirect URL in Supabase auth still points to localhost, check Authentication then URL configuration. i fix this kind of thing for people, message me if you want a hand&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Step 4: move to DMs, then close
&lt;/h2&gt;

&lt;p&gt;When someone replies "yes please" or sends a DM, the hard part is over. Ask one or two questions about their setup, give a fixed price, and offer to start today. Speed wins here: the person who answers within an hour usually gets the job.&lt;/p&gt;

&lt;h2&gt;
  
  
  How not to get banned
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Read each subreddit's rules. Some ban any self-promotion, respect that.&lt;/li&gt;
&lt;li&gt;Do not post the same reply twice. Reddit spots copy-paste fast.&lt;/li&gt;
&lt;li&gt;Keep the ratio healthy: most of your comments should be plain help with no offer at all.&lt;/li&gt;
&lt;li&gt;A few good replies a day beat fifty lazy ones.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  What to expect
&lt;/h2&gt;

&lt;p&gt;Most replies go nowhere, and that is fine. You are playing a numbers game with very warm leads: a handful of helpful replies a day, a few conversations a week, and every now and then someone who says "can you just do it for me". It costs half an hour a day, and the people you talk to came asking for help.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  How do I find people who want to buy on Reddit?
&lt;/h3&gt;

&lt;p&gt;You should look for posts where people specifically ask for tools, alternatives, or help fixing a concrete problem. Search for these buying phrases in small, specific subreddits where your customers actually hang out. You can check these manually or use a tool like Reddit Scraper &amp;amp; AI Lead Finder to automate the search.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I put links in my Reddit comments?
&lt;/h3&gt;

&lt;p&gt;Do not include links in your first reply to a user. Links from new accounts often get filtered out or downvoted. Instead, offer a helpful tip and tell the person to message you directly if they want more help.&lt;/p&gt;

&lt;h3&gt;
  
  
  How can I avoid getting banned when selling on Reddit?
&lt;/h3&gt;

&lt;p&gt;Read the rules of each subreddit and respect any bans on self-promotion. Make sure most of your comments just offer help without pitching your product at all. Never copy and paste the same reply twice because Reddit spots this very quickly.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://watershowdigital.com/blog/find-customers-on-reddit" rel="noopener noreferrer"&gt;watershowdigital.com/blog/find-customers-on-reddit&lt;/a&gt;.&lt;/em&gt; Need a hand with your app or automation? &lt;a href="https://watershowdigital.com/build" rel="noopener noreferrer"&gt;WaterShow Digital&lt;/a&gt; fixes and builds it, fixed quote first.&lt;/p&gt;

</description>
      <category>reddit</category>
      <category>marketing</category>
      <category>startup</category>
      <category>saas</category>
    </item>
    <item>
      <title>Supabase RLS blocks your inserts? Six causes and how to fix each</title>
      <dc:creator>WaterShow</dc:creator>
      <pubDate>Mon, 26 Oct 2026 01:57:09 +0000</pubDate>
      <link>https://dev.to/watershow/supabase-rls-blocks-your-inserts-six-causes-and-how-to-fix-each-4nc7</link>
      <guid>https://dev.to/watershow/supabase-rls-blocks-your-inserts-six-causes-and-how-to-fix-each-4nc7</guid>
      <description>&lt;p&gt;You turned on Row Level Security, wrote a policy that looks right, and now every insert from your app fails with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;new row violates row-level security policy for table "todos"
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The good news: this error almost always comes from one of six causes. Go through them in order and you will find yours in a few minutes.&lt;/p&gt;

&lt;h2&gt;
  
  
  1. There is no INSERT policy at all
&lt;/h2&gt;

&lt;p&gt;When RLS is on, everything is denied until a policy allows it. A lot of apps have a policy for &lt;code&gt;SELECT&lt;/code&gt; (often copied from a tutorial) but nothing for &lt;code&gt;INSERT&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Check what you have:&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;select&lt;/span&gt; &lt;span class="n"&gt;policyname&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;cmd&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;roles&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;qual&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;with_check&lt;/span&gt;
&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="n"&gt;pg_policies&lt;/span&gt;
&lt;span class="k"&gt;where&lt;/span&gt; &lt;span class="n"&gt;tablename&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'todos'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If there is no row with &lt;code&gt;cmd = 'INSERT'&lt;/code&gt; (or &lt;code&gt;ALL&lt;/code&gt;), add one:&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="n"&gt;policy&lt;/span&gt; &lt;span class="nv"&gt;"users insert own rows"&lt;/span&gt;
&lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;insert&lt;/span&gt;
&lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;authenticated&lt;/span&gt;
&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="k"&gt;check&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  2. The policy uses USING instead of WITH CHECK
&lt;/h2&gt;

&lt;p&gt;For inserts, Postgres only looks at &lt;code&gt;with check&lt;/code&gt;. A &lt;code&gt;using&lt;/code&gt; clause is for rows that already exist (select, update, delete). If you wrote the insert rule into &lt;code&gt;using&lt;/code&gt;, Postgres either rejects the policy or the insert still fails.&lt;/p&gt;

&lt;p&gt;Rule of thumb:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;select / delete&lt;/strong&gt;: &lt;code&gt;using (...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;insert&lt;/strong&gt;: &lt;code&gt;with check (...)&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;update&lt;/strong&gt;: both, &lt;code&gt;using&lt;/code&gt; for which rows you may touch, &lt;code&gt;with check&lt;/code&gt; for what they may become&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  3. user_id is empty, so the check can never pass
&lt;/h2&gt;

&lt;p&gt;Your policy says &lt;code&gt;auth.uid() = user_id&lt;/code&gt;, but the client sends the row without &lt;code&gt;user_id&lt;/code&gt;. Null is not equal to anything, so the check fails.&lt;/p&gt;

&lt;p&gt;Either send it from the client, or better, let the database fill it in:&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;alter&lt;/span&gt; &lt;span class="k"&gt;table&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt;
&lt;span class="k"&gt;alter&lt;/span&gt; &lt;span class="k"&gt;column&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt; &lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the client can insert &lt;code&gt;{ title: "Buy milk" }&lt;/code&gt; and the row is still owned by the right user.&lt;/p&gt;

&lt;h2&gt;
  
  
  4. The request is not actually logged in
&lt;/h2&gt;

&lt;p&gt;&lt;code&gt;auth.uid()&lt;/code&gt; returns null when the request comes in as &lt;code&gt;anon&lt;/code&gt;. This happens more often than you would think:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;the user's session expired and the client did not refresh it&lt;/li&gt;
&lt;li&gt;you call Supabase from a server route or an edge function with the anon key, but never pass the user's access token&lt;/li&gt;
&lt;li&gt;the policy says &lt;code&gt;to authenticated&lt;/code&gt;, while the request arrives as &lt;code&gt;anon&lt;/code&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;On the server, create the client with the user's token, so Postgres knows who is asking:&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;supabase&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nf"&gt;createClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;url&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;anonKey&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;global&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;headers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;Authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;`Bearer &lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;accessToken&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="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  5. insert().select() also needs a SELECT policy
&lt;/h2&gt;

&lt;p&gt;This one catches almost everybody. If you write:&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="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;data&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;error&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;supabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;todos&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;insert&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;title&lt;/span&gt; &lt;span class="p"&gt;}).&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Supabase inserts the row and then reads it back. Reading it back is a &lt;code&gt;select&lt;/code&gt;, so you also need a select policy for that row. Without it the whole call fails with the same RLS error, even though your insert policy is fine.&lt;/p&gt;

&lt;p&gt;Either add the select policy:&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="n"&gt;policy&lt;/span&gt; &lt;span class="nv"&gt;"users read own rows"&lt;/span&gt;
&lt;span class="k"&gt;on&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="k"&gt;select&lt;/span&gt;
&lt;span class="k"&gt;to&lt;/span&gt; &lt;span class="n"&gt;authenticated&lt;/span&gt;
&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;auth&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;uid&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;user_id&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;or drop the &lt;code&gt;.select()&lt;/code&gt; if you do not need the row back.&lt;/p&gt;

&lt;h2&gt;
  
  
  6. A related table has its own rules
&lt;/h2&gt;

&lt;p&gt;If your insert fires a trigger that writes into another table, or the policy itself runs a subquery on another table (for example "is this user a member of this team?"), those tables have RLS too. The check fails because the subquery returns nothing for this user.&lt;/p&gt;

&lt;p&gt;Two ways out: give the user read access to the rows the check needs, or move the check into a &lt;code&gt;security definer&lt;/code&gt; function that runs with the owner's rights. Keep that function small and only return what the check needs.&lt;/p&gt;

&lt;h2&gt;
  
  
  How to test a policy without guessing
&lt;/h2&gt;

&lt;p&gt;The SQL editor in the dashboard runs as a superuser, which skips RLS. So a query that works there tells you nothing. Pretend to be the user instead:&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;begin&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;local&lt;/span&gt; &lt;span class="k"&gt;role&lt;/span&gt; &lt;span class="n"&gt;authenticated&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;set&lt;/span&gt; &lt;span class="k"&gt;local&lt;/span&gt; &lt;span class="n"&gt;request&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;jwt&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;claims&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'{"sub": "PASTE-A-REAL-USER-ID"}'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;insert&lt;/span&gt; &lt;span class="k"&gt;into&lt;/span&gt; &lt;span class="k"&gt;public&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;todos&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;values&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'test'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;rollback&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If this fails, the problem is in your policies. If it works, the problem is in how your app sends the request (causes 4 and 5).&lt;/p&gt;

&lt;h2&gt;
  
  
  What not to do
&lt;/h2&gt;

&lt;p&gt;Do not "fix" it by turning RLS off, and do not put the &lt;code&gt;service_role&lt;/code&gt; key in the browser. Both make the error go away by giving everyone access to every row. The first person who opens the network tab gets your whole database.&lt;/p&gt;

&lt;h2&gt;
  
  
  FAQ
&lt;/h2&gt;

&lt;h3&gt;
  
  
  Why does Supabase insert().select() fail with an RLS error?
&lt;/h3&gt;

&lt;p&gt;When you add the select method to an insert command, Supabase tries to read the row back after creating it. This means you need a select policy in addition to your insert policy. If you do not have a select policy, the entire call fails.&lt;/p&gt;

&lt;h3&gt;
  
  
  How do I test Supabase RLS policies in the SQL editor?
&lt;/h3&gt;

&lt;p&gt;The SQL editor runs as a superuser and naturally skips RLS rules. To test a policy correctly, you need to write a transaction that sets the local role to authenticated and provides a real user ID. If the query works this way, your policies are fine and the problem is in your app code.&lt;/p&gt;

&lt;h3&gt;
  
  
  Should I use using or with check for an insert policy?
&lt;/h3&gt;

&lt;p&gt;You must use with check for insert policies. Postgres only looks at the using clause for rows that already exist, such as when you select or delete data. If you write your insert rule with using, Postgres will reject it and the insert will fail.&lt;/p&gt;




&lt;p&gt;&lt;em&gt;Originally published at &lt;a href="https://watershowdigital.com/blog/supabase-rls-blocks-inserts" rel="noopener noreferrer"&gt;watershowdigital.com/blog/supabase-rls-blocks-inserts&lt;/a&gt;.&lt;/em&gt; Need a hand with your app or automation? &lt;a href="https://watershowdigital.com/build" rel="noopener noreferrer"&gt;WaterShow Digital&lt;/a&gt; fixes and builds it, fixed quote first.&lt;/p&gt;

</description>
      <category>supabase</category>
      <category>postgres</category>
      <category>security</category>
      <category>webdev</category>
    </item>
  </channel>
</rss>
