Originally published at chudi.dev
I shipped broken code three times in one week. The AI said "should work." I believed it.
So I built a cross-posting system with a 72-hour delay. Not because it's slow. Because fast broke everything.
Why Canonical SEO Matters
When you publish identical content in two places, search engines have to decide which one is "real." They use the canonical URL—a signal you set explicitly via <link rel="canonical" href="..."> in your page's <head>—to resolve this.
If your original post goes live at chudi.dev/blog/my-post and the Dev.to cross-post appears at dev.to/chudi/my-post, both pages might be crawled within hours of each other. The Google Search Central documentation on duplicate URLs confirms that even with canonical tags, Google weighs crawl timing, inbound links, and page speed as signals. Dev.to has stronger domain authority than most personal blogs. If their version is indexed first, the canonical hint sometimes gets overridden by authority signals.
The canonical tag in Dev.to's editor is a genuine safety net. But "safety net" implies a fall is possible. The 72-hour delay eliminates the need for the net.
The Problem With Instant Cross-Posting
When you publish a blog post and immediately cross-post to Dev.to, you're racing Google. Dev.to has strong domain authority. If their version gets indexed before your canonical URL, search engines might treat their copy as the original.
Your content. Their SEO credit.
The canonical URL tag in Dev.to posts is supposed to prevent this. But "supposed to" is the same energy as "should work." I've been burned by that confidence before. This is similar to the challenges covered in AEO (Answer Engine Optimization), where timing and discovery order matter significantly.
The 72-Hour Solution
The system is simple:
RSS Feed (chudi.dev/rss.xml)
↓ (polls every 2 minutes)
72-hour Delay (let Google index canonical)
↓
Filter (AI OR Claude OR automation keywords)
↓
Slack #social notification with CLI command
After 72 hours, Google has had time to crawl and index. The canonical relationship is established. Now it's safe to cross-post.
Why Slack + Manual CLI?
The notification looks like this:
📝 Ready to cross-post: "I Built a 72-Hour Delay..."
Run:
pnpm cross-post devto-cross-posting-automation --post devto
I copy the command. I run it. I verify the output.
This manual step is intentional. The system could auto-publish. I won't let it.
Not because the tech can't handle it. Because that "should work" confidence is exactly what shipped broken code three times.
The Filter Logic
Not every post needs cross-posting. The Zapier filter checks for:
- AI/Claude/automation content (Dev.to audience match)
- Technical depth (tutorials, guides, architecture posts)
- Relevance to the developer community
Personal essays stay on the main blog. Technical content gets distributed. This approach mirrors the selectivity described in multi-agent architecture systems, where routing decisions determine which paths process which workloads.
Setting It Up
Step 1: RSS Trigger
- App: RSS by Zapier
- Trigger: New Item in Feed
- Feed URL: Your blog's RSS feed
- Poll interval: 2 minutes (or whatever Zapier allows)
Step 2: Delay
- App: Delay by Zapier
- Action: Delay For
- Duration: 72 hours
Step 3: Filter
- App: Filter by Zapier
- Condition: Title contains "AI" OR "Claude" OR "automation" OR "agent"
- Continue if: Matches
Step 4: Slack Notification
- App: Slack
- Action: Send Channel Message
- Channel: #social (or wherever you track content tasks)
- Message: Template with post title + CLI command
Cross-Posting to Other Platforms
The same system works for Hashnode and Medium with minor adjustments.
Hashnode: Set the canonical URL in post settings (under "SEO" tab). Their indexing speed is slower than Dev.to, so a 48-hour delay is usually sufficient. Hashnode's audience skews more technical and overlaps less with your personal blog's reader base—lower duplicate traffic, higher reach.
Medium: Medium lets you import posts directly from a URL and auto-sets the canonical. The catch: Medium's Partner Program requires exclusive content, so if you're monetizing there, cross-posting is off the table. For non-monetized cross-posting, 72 hours applies.
LinkedIn Articles: LinkedIn doesn't crawl or index aggressively. A 24-hour delay is enough. The audience is different enough (professional network vs. developers) that content slightly rewritten for context performs better than a straight copy.
For each platform, the Zapier Zap gets a separate branch: filter by keyword, check platform relevance, delay accordingly, send the appropriate CLI command. The core delay-then-notify pattern is identical.
The Philosophy Behind the Delay
Constraints often become features.
The 72-hour delay felt like a limitation when I first designed it. Now it's the whole point. It forces patience. It prevents the "ship it and forget it" pattern that creates SEO problems months later.
The manual CLI step felt like friction. Now it's verification. Every cross-post gets a human checkpoint.
I could make this fully automated. I could remove the delay. I could trust that everything will work.
But I've learned what "should work" really means: untested assumptions waiting to become problems. The principle here—verification before automation—is fundamental to the AI automation architecture I've documented elsewhere, where human checkpoints prevent silent failures.
What This Prevents
- Duplicate content penalties: Canonical URL is indexed first
- Silent failures: You see the Slack notification and verify
- Over-automation regret: You control what gets cross-posted
- "Should work" deployments: Every action is verified
The system is slower than it could be. That's the feature.
Measuring If It's Working
After running this for 30 days, two checks confirm the system is doing its job:
Check 1: Google Search Console — Index Coverage
Go to URL Inspection for your original post. Check that Google has indexed chudi.dev/blog/my-post (not the Dev.to URL) as the canonical. If Dev.to's URL appears, the canonical signal wasn't respected. Look at the indexed date—it should predate the Dev.to publication date by at least 48 hours.
Check 2: Referral traffic split
In your analytics, compare traffic from dev.to referrals vs. direct organic traffic to your post. If Dev.to cross-posts drive more traffic than the original, the canonical relationship is working correctly. Dev.to is amplifying your content and sending traffic back, not cannibalizing your search rankings.
If organic rankings for the post are lower than expected, check whether Dev.to indexed first. It's diagnosable—the evidence is in GSC's URL Inspection tool.
Troubleshooting: When the Delay Isn't Enough
The 72-hour delay handles the most common scenario: original post goes live, Google crawls it, canonical relationship established before Dev.to appears. But a few edge cases can still cause problems.
Google crawls slowly on new domains. If your blog is less than six months old and hasn't built crawl frequency yet, Google might not visit for 5-7 days. For new sites, extend the delay to 5 days, or manually request indexing via Google Search Console immediately after publishing. The URL Inspection tool's "Request Indexing" button is free and triggers a fresh crawl within 24 hours.
Dev.to has high crawl priority. Dev.to gets crawled multiple times per day because of its domain authority and publishing frequency. Even with a 72-hour delay, if your original post wasn't crawled before the Dev.to cross-post goes live, Dev.to's version might still be indexed first. Run the URL Inspection check within 48 hours of every publish to confirm your original was indexed before you cross-post.
The canonical tag can silently fail. Dev.to's editor sets the canonical URL when you create the article. If you edit the Dev.to post afterward, verify the canonical is still set—I've seen it revert to the Dev.to URL on post edits. Check by viewing the page source of your Dev.to post and searching for rel="canonical".
When in doubt, GSC's URL Inspection tool tells you exactly which URL Google treats as canonical. Check it after every cross-post for the first few months until you trust the pattern. The goal is to see your original URL listed as canonical, not Dev.to's.
FAQ
Why wait 72 hours before cross-posting to Dev.to?
Google needs time to crawl and index your original post as the canonical source. If Dev.to gets indexed first, search engines might treat the cross-post as the original, hurting your site's SEO.
Why not fully automate the cross-posting?
Automation without verification leads to silent failures. A Slack notification with a manual CLI command ensures you verify the post is ready and nothing broke during the delay period.
What triggers the cross-posting notification?
An RSS feed trigger in Zapier monitors your blog's RSS feed, applies a 72-hour delay, filters for relevant keywords (AI, Claude, automation), then sends a Slack message with the CLI command to run.
How does the keyword filter work?
Zapier's filter step checks the post title and content for keywords like 'AI', 'Claude', 'automation', 'agent'. Only matching posts trigger notifications, so you're not prompted to cross-post every article.
Maybe the goal isn't faster automation. Maybe it's building systems that force us to verify before we trust--and making "should work" impossible to accept. The 72-hour delay is a constraint that became a feature. The manual CLI step is friction that became a quality gate. Both are intentional choices that make the system more reliable, not less useful.
Top comments (0)