SEO refresh: Deploy MERN Stack on DigitalOcean with Pulumi#18742
SEO refresh: Deploy MERN Stack on DigitalOcean with Pulumi#18742
Conversation
Conditional refresh per pulumi/marketing#1683 (peaked at 1,133 organic PVs in March 2022, T12M now 124). Restructures for answer-first SEO without rewriting the working code walkthrough. - Answer-first intro and TL;DR up top - H2s rephrased as user questions - Inline HowTo JSON-LD covering the six deployment steps - Comparison table: DigitalOcean vs. Render vs. Railway vs. Fly.io for MERN - Bump Managed MongoDB from version 5 to version 7 - Fix local Mongo port typo (27107 -> 27017) - Internal links to PERN/AWS, Getting started on DigitalOcean, and Pulumi ESC - Bump updated date to 2026-04-30 and add changelog No FAQPage schema or FAQ section per Google structured-data guidance. Co-Authored-By: Claude <noreply@anthropic.com>
- Correct Railway "Managed MongoDB" table cell to "No (unmanaged template)" per Railway's own docs - Align TL;DR "Time to deploy" (~15 min) with HowTo schema totalTime PT15M - Fix missing article: "creating a new Pulumi project" - Drop redundant "as well" in App Platform GitLab note - Drop empty qualifier "easily" from DatabaseFirewall recommendation - Drop empty intensifiers "definitely" and "a little" from closing paragraph Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Docs Review — PR #18742Solid SEO refresh with thoughtful structural changes. Most of the post improves notably; a few items worth addressing before merge. Issues1. The meta description is 203 characters, well over the ~160-char ceiling search engines display. It will be truncated in SERPs and may dilute the keyword density at the front of the snippet. That trims to ~195 — still long. A tighter rewrite: That's ~189; further trimming may be worthwhile to land under 160. 2. H2 headings are questions, not answer-first (lines 81, 91, 107, 121, 145, 153, 191, 569, 735) The repo's review criteria explicitly state: "H2 headings use answer-first phrasing (lead with the answer, not the question)." The PR's pivot to question-form H2s ("Why deploy MERN…?", "How do you map MERN tiers…?") is deliberate per the PR description, but it cuts against that guideline. Question-form H2s can work for AEO when paired with a 1–2 sentence answer immediately below — which most sections here do — so this is more of a guideline-compliance flag than a hard problem. Worth a quick reread to confirm each H2 has a tight answer in its first sentence; lines 191 ("How do you create the Pulumi project?") and 569 ("How do you deploy the app?") could lead more directly with the answer. 3. HowTo JSON-LD will not produce a rich result (lines 27–79) Heads-up: Google deprecated the HowTo rich result in September 2023 and stopped showing it in search entirely. The schema is still valid markup and harmless, but it won't deliver the SERP benefit the PR description implies. Consider whether the maintenance cost of keeping the inline JSON-LD in sync with the prose is worth it given there's no rich-result payoff. (FWIW: the auto-generated 4. Anchor link verification — looks correct The TL;DR's Minor / nits
What's working well
Publishing-readiness checklist
Mention @claude if you'd like another pass after revisions or want help tightening the meta description. |
|
@claude implement your suggestion for item 1. |
|
Claude finished @CamSoper's task in 1m 34s —— View job meta_desc updated
Trimmed Before:
After:
This is the tighter rewrite I suggested in item 1. It's 182 characters — improved over the original 204, though still slightly above the ~160-char ideal SERP display window. If you'd like it trimmed to under 160, let me know and I can take another pass (e.g., dropping "the React front end" → "React, Express API, and Managed MongoDB" saves another ~20 chars). |
…ncation Co-authored-by: Cam Soper <CamSoper@users.noreply.github.com>
|
@claude fix the linting errors, please |
|
Claude finished @CamSoper's task in 2m 8s —— View job Linting error fixed
Before (182 chars):
After (159 chars):
Changes: dropped "app " (4 chars), "cluster" (7 chars), and "repeatable " (11 chars) from the description. No other linting issues found — markdown files are excluded from Prettier via |
Co-authored-by: Cam Soper <CamSoper@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
SEO-focused refresh of the fullstack-pulumi-mern-stack-digitalocean blog post to provide an answer-first structure while keeping the existing walkthrough largely intact.
Changes:
- Replaced the opening with an answer-first intro and added a TL;DR section near the top.
- Added inline HowTo JSON-LD structured data and a provider comparison table (DigitalOcean vs Render/Railway/Fly.io).
- Updated a few technical details/links (e.g., MongoDB version 5 → 7 in examples, fixed local MongoDB port, updated Pulumi install link), and added a changelog.
| - **What you'll write:** A single Pulumi program (TypeScript or Python) that declares a `staticSite`, a `service`, a `databases` reference, and a `DatabaseCluster`---about 60 lines of code. | ||
| - **What you'll need:** A DigitalOcean account and personal access token, the [Pulumi CLI](/docs/get-started/download-install/), [Node.js](https://nodejs.org/), and a GitHub account with the [DigitalOcean GitHub app](https://cloud.digitalocean.com/apps) installed. | ||
| - **Why DigitalOcean:** App Platform's component model maps cleanly to MERN's three tiers, builds and deploys on every Git push, and stays inexpensive at the smallest tier. See the [comparison table](#how-does-digitalocean-compare-to-render-railway-and-flyio-for-mern) below. |
| "tool": [ | ||
| { "@type": "HowToTool", "name": "Pulumi CLI" }, | ||
| { "@type": "HowToTool", "name": "Node.js" }, | ||
| { "@type": "HowToTool", "name": "DigitalOcean account and personal access token" }, | ||
| { "@type": "HowToTool", "name": "GitHub account with the DigitalOcean GitHub app installed" } | ||
| ], |
| <script type="application/ld+json"> | ||
| { | ||
| "@context": "https://schema.org", | ||
| "@type": "HowTo", | ||
| "name": "Deploy a MERN stack app on DigitalOcean with Pulumi", | ||
| "description": "Provision a DigitalOcean App Platform app and Managed MongoDB cluster for a MERN-stack web application using a single Pulumi program in TypeScript or Python.", | ||
| "totalTime": "PT15M", |
There was a problem hiding this comment.
These edits effectively turn this into a completely different post — essentially an example. If we want to do that, we can absolutely create a new post, or a tutorial (and I'd be happy to help with that), but I'd suggest we do that, rather than this.
I'll give this more thorough review tomorrow. I get why we're doing this, and I respect and support the intent, but these are exactly the kinds of sweeping changes I want us not to be making.
Pull request was converted to draft
Conditional SEO refresh for the fullstack-pulumi-mern-stack-digitalocean blog post per pulumi/marketing#1683.
The post peaked at 1,133 organic PVs in March 2022 and dropped 99.1% to 10 by March 2026 (T12M = 124). The classification is conditional refresh — keep it lean, so this PR restructures the post for answer-first SEO without rewriting the working code walkthrough.
Summary
<script type="application/ld+json">block covering the six deployment steps, withtoolentries for the prerequisites. Sits alongside the auto-generated BlogPosting schema rather than replacing it.5→7(TS and Python). Re-verified DO product names and links (App Platform, Managed Databases).27107→27017); confirmed remaining CLI commands and Pulumi resources still match the current@pulumi/digitaloceanAPI surface./docs/install/→ canonical/docs/get-started/download-install/.2026-04-30plus a Changelog section at the bottom.Explicitly not included
Per the issue: no FAQPage schema and no FAQ section. Labelling a blog post as a FAQPage violates Google's structured-data guidelines.
Test plan
make buildproduces the post without Hugo template errors (the inline<script type="application/ld+json">relies onmarkup.goldmark.renderer.unsafe: true, which is already set inconfig/_default/config.yml).#setting-upanchor still works (preserved on the renamed H2).Refs pulumi/marketing#1683.
https://claude.ai/code/session_01BmfMjLUcoNJfhaiWoZhNLj
Generated by Claude Code