RemodelFinder SEO Master Plan
Dual lens: SEO strategy + software architecture. This document covers every lever available β internal content differentiation, technical infrastructure, and external link acquisition. Treat each section as a sprint-ready backlog.
Situation Assessment
What We Have
- ~260,000 ZIP Γ project pages (
/pro/{project}/{zip}/)
- ~25,000 city hub pages (
/{state}/{city}/)
- ~50 state hub pages (
/{state}/)
- 10 project hub pages (
/pro/{project}/)
- D1 database at edge with cost multipliers, seasonal data, permit density, regional notes
- Solid schema: Product, Service, FAQPage, BreadcrumbList on every ZIP page
- Fast delivery via Cloudflare Workers + edge rendering
The Core Problem
Google has 71,000+ pages discovered but not indexed. That is not a content quality signal β it is a crawl budget and content differentiation problem. The ZIP pages are unique in data but nearly identical in prose structure. Google's classifier sees them as near-duplicate templates at scale and deprioritizes them. The fix is two-pronged: earn crawl authority through backlinks, and earn indexation through content that is genuinely different from page to page.
Priority Ranking
- Content differentiation on ZIP pages (indexation blocker)
- Technical crawl optimization (crawl budget)
- E-E-A-T and entity establishment (trust)
- Link building β digital PR first, then niche outreach
- New page type expansion (surface area)
Part 1: Technical SEO Foundation
1.1 Crawl Budget Optimization
robots.txt β Add disallow rules for low-value crawl paths:
User-agent: *
Disallow: /api/
Disallow: /_astro/
Disallow: /cdn-cgi/
Crawl-delay: 1
Sitemap priority signals β Update the per-project sitemaps to use <priority> differentiation:
- Major metros (ZIP in top 50 CBSAs):
<priority>0.9</priority>
- Mid-tier ZIPs:
<priority>0.7</priority>
- Rural/low-population ZIPs:
<priority>0.5</priority>
Implementation: add a metro_tier column (1/2/3) to the zips D1 table, join it in the sitemap endpoint, emit tiered priority values.
Sitemap split strategy β Current sitemaps have 26,283 URLs each, which is fine on size but not on crawl signaling. Split each project sitemap by state:
/sitemaps/roofing-costs-ca.xml (California ZIPs for roofing)
/sitemaps/roofing-costs-tx.xml (Texas ZIPs for roofing)
...
This lets Google schedule crawl by geography, surfaces state-level authority, and makes re-submission surgical when data changes.
Lastmod accuracy β The current TODAY approach tags every page as modified today on every build. Google penalizes fake freshness. Fix: store a last_data_update timestamp per ZIP in D1 (updated only when underlying data actually changes), and emit that as <lastmod> in sitemaps.
1.2 Core Web Vitals
The edge rendering already handles TTFB. Focus areas:
- LCP: The cost card is above the fold. Ensure the ROI gauge canvas does not block render. Add
loading="eager" to any above-fold images; everything else gets loading="lazy".
- CLS: Pin explicit width/height on the ROI canvas element. Avoid injecting the zip-banner without a reserved height slot.
- INP: The zip-banner fetch happens on page load. Defer it with
requestIdleCallback so it does not compete with initial interaction handlers.
1.3 Schema Enhancements
Add to every ZIP page:
{
"@type": "Dataset",
"name": "Remodeling Cost Data for {ZIP}",
"description": "ZIP-level cost estimates for {project} in {city}, {state}",
"creator": { "@type": "Organization", "name": "RemodelFinder" },
"dateModified": "{YYYY-MM-DD}",
"license": "https://remodelfinder.com/terms",
"spatialCoverage": {
"@type": "Place",
"address": { "@type": "PostalAddress", "postalCode": "{ZIP}", "addressRegion": "{STATE}" }
}
}
Add to project hub pages:
{
"@type": "ItemList",
"name": "Top Markets for {PROJECT}",
"itemListElement": [... top 10 cities by search volume ...]
}
Add SpeakableSpecification to FAQ answers β this captures voice search and AI overview snippets:
{
"@type": "SpeakableSpecification",
"cssSelector": ["#faq-answer-1", "#faq-answer-2"]
}
Review schema β Add editorial quality scores with your own methodology:
{
"@type": "Review",
"reviewRating": { "@type": "Rating", "ratingValue": "4.2", "bestRating": "5" },
"author": { "@type": "Organization", "name": "RemodelFinder Editorial" },
"reviewBody": "Based on 2026 Cost vs. Value data and local permit activity..."
}
1.4 Canonical and Hreflang
Every dynamic page must emit a self-referencing canonical. Verify that SSR pages in the Cloudflare Worker are always setting:
<link rel="canonical" href="https://remodelfinder.com/pro/{project}/{zip}/" />
Check that trailing slashes are always consistent β a mix of /pro/roofing-costs/10001 and /pro/roofing-costs/10001/ creates duplicate indexation. The trailingSlash: 'always' Astro config handles this at the framework level, but verify the Worker is also issuing 301s for non-trailing-slash inbound links.
1.5 Meta Robots for Thin Clusters
A subset of ZIP codes are PO Boxes, military APO/FPO addresses, or have near-zero residential population. These pages have a real cost multiplier but no real homeowner search intent. Add a is_residential boolean to the zips table and for non-residential ZIPs, emit:
<meta name="robots" content="noindex, follow" />
This removes crawl waste without killing the internal link value.
Part 2: Internal SEO β Content Differentiation
This is the highest-priority work. Google is not indexing 71K pages because they look too similar. The fix is architectural: add data dimensions that produce genuinely different prose per ZIP.
2.1 The Problem in Concrete Terms
Right now, /pro/roofing-costs/60601/ (Chicago Loop) and /pro/roofing-costs/60602/ (adjacent Chicago ZIP) render:
- Same project scope section (word for word)
- Same decisions/timing section (word for word)
- Same project-specific FAQs (with only city/state name swapped)
- Same regional note (same
region_id)
- Different numbers but identical sentence structures
Google's duplicate content classifier does not look at numbers. It looks at n-gram similarity in prose. Adjacent ZIPs in the same city/region are flagged as near-duplicates.
2.2 Data Expansion β New D1 Columns and Tables
These additions unlock content variation without AI generation costs.
Table: zip_demographics (source: US Census ACS 5-year estimates)
CREATE TABLE zip_demographics (
zip TEXT PRIMARY KEY,
median_year_built INTEGER, -- housing stock age
owner_occupied_pct REAL, -- % owner-occupied units
pct_single_family REAL, -- % single-family detached
hoa_prevalence_tier INTEGER, -- 1=low, 2=medium, 3=high (CBSA-level proxy)
population_density_tier INTEGER -- 1=rural, 2=suburban, 3=urban, 4=dense urban
);
Table: zip_risk_zones (source: FEMA NFIP, NOAA storm data)
CREATE TABLE zip_risk_zones (
zip TEXT PRIMARY KEY,
flood_zone TEXT, -- X, AE, VE, etc.
hail_risk_tier INTEGER, -- 1-5 (NOAA hail frequency)
hurricane_risk_tier INTEGER, -- 1-5
wildfire_risk_tier INTEGER, -- 1-5
freeze_thaw_cycles_per_yr INTEGER
);
Table: state_regulations (source: state contractor licensing boards)
CREATE TABLE state_regulations (
state TEXT PRIMARY KEY,
contractor_license_required BOOLEAN,
permit_required_threshold_usd INTEGER, -- dollar amount above which permits required
homeowner_exception BOOLEAN, -- can homeowners pull their own permits?
sales_tax_on_labor BOOLEAN,
sales_tax_rate REAL,
hic_registration_required BOOLEAN -- Home Improvement Contractor registration
);
Extend zips table:
ALTER TABLE zips ADD COLUMN metro_tier INTEGER DEFAULT 2; -- 1=major, 2=mid, 3=rural
ALTER TABLE zips ADD COLUMN census_division TEXT; -- New England, Mountain, etc.
ALTER TABLE zips ADD COLUMN utility_rate_tier INTEGER; -- 1=low, 2=avg, 3=high (energy costs)
2.3 Content Module System β Architecture
Replace the current monolithic [zip].astro prose blocks with a content module system where each module selects a copy variant based on data signals. Every module has 3-5 variant templates; the selected variant is determined by data thresholds.
Module: Housing Stock Age
Condition: median_year_built < 1960
β "Older homes in {city} β median build year {year} β often require code updates before {project} work begins.
Budget an additional 10β20% for surprises: knob-and-tube wiring, asbestos-backed materials,
or undersized framing that won't pass current inspection."
Condition: median_year_built 1960β1985
β "Much of {city}'s housing stock dates to the post-war expansion era.
{Project} on these homes is typically straightforward, though {specific_gotcha_per_project}."
Condition: median_year_built > 2000
β "Newer construction in {city} means {project} is usually a clean replacement β
no hidden remediation, standard framing, modern materials compatibility."
Module: Density / Labor Market
Condition: population_density_tier = 4 (dense urban)
β "In dense urban {city}, contractor logistics add cost: parking permits, material lifts
for multi-story buildings, and restricted work hours in residential zones.
Factor this into your bid comparison."
Condition: population_density_tier = 1 (rural)
β "Rural {county} has fewer contractors competing for work, which cuts both ways:
less scheduling pressure in peak season, but fewer bids to compare.
Get at least three quotes before committing."
Module: Risk Zone Context (project-specific)
For roofing in high hail-risk ZIPs:
hail_risk_tier >= 4
β "{city} sits in a high-frequency hail corridor. Impact-resistant shingles
(Class 4 rating) cost 10β20% more but can earn a meaningful insurance discount
β some carriers in {state} offer 20β30% premium reductions.
Ask your insurer before choosing materials."
For HVAC in high utility-rate ZIPs:
utility_rate_tier = 3
β "With electricity rates in {county} running above the national average,
the ROI math on a high-efficiency unit (18+ SEER) is stronger here than most markets.
The payback period shortens by 2-4 years compared to a standard-efficiency replacement."
Module: Regulatory Context
permit_required_threshold_usd < 1000 AND project.base_cost > permit_required_threshold_usd
β "{state} requires a permit for {project} work above ${threshold}.
In {county}, expect 2-4 weeks for permit approval.
A licensed contractor handles this β but verify it's included in the contract."
homeowner_exception = TRUE
β "Homeowners in {state} can pull their own permits for {project} work,
which some use to reduce costs on straightforward jobs.
That said, unpermitted work can complicate resale."
Module: HOA Consideration
hoa_prevalence_tier = 3
β "{city}'s {census_division} location has a high proportion of HOA-governed communities.
Before signing a contract, verify your HOA's approved material list β
specific shingle colors, siding profiles, and door styles are commonly restricted."
2.4 FAQ Expansion Strategy
Current FAQs swap city/state into fixed templates. Expand to a FAQ bank with variant selection:
Per-project FAQ bank (target: 15-20 FAQs per project, 3-5 shown per ZIP)
Selection logic:
// Select FAQs based on ZIP data signals
const faqs = [];
faqs.push(baseFaqs[0]); // always: cost in city
faqs.push(baseFaqs[1]); // always: worth it in city
if (zip.hail_risk_tier >= 4) faqs.push(faqBank.roofing.hailResistant);
if (zip.median_year_built < 1970) faqs.push(faqBank.roofing.oldHome);
if (zip.population_density_tier >= 3) faqs.push(faqBank.roofing.urbanLogistics);
if (state_regulations.permit_required) faqs.push(faqBank.roofing.permits);
if (roi_score >= 80) faqs.push(faqBank.roofing.highRoiRationale);
if (roi_score < 50) faqs.push(faqBank.roofing.lowRoiRationale);
if (seasonal.demand_label === 'Peak') faqs.push(faqBank.roofing.peakSeasonTiming);
Each FAQ in the bank is written with location variable slots. The selection logic guarantees that adjacent ZIPs in the same city region get different FAQ combinations based on their data profile.
New FAQ topics to write per project:
- What does a permit cost for {project} in {state}?
- Can I DIY {project} in {state}?
- How does {city}'s {climate_zone} climate affect {project} longevity?
- What warranty should I expect for {project} in {year}?
- How do I find a licensed {project} contractor in {county}?
- Does homeowner's insurance cover {project} in flood zone {flood_zone}?
- What's the ROI on {project} for a {median_year_built}-era home?
2.5 New Page Types β Programmatic Expansion
These create new URL surfaces and internal link depth.
A. City Comparison Pages
/compare/{city-a}-vs-{city-b}/{project}/
Example: /compare/chicago-il-vs-milwaukee-wi/roofing-costs/
Content: Side-by-side cost estimate, ROI score, seasonal timing, permit environment. Generated for city pairs within 150 miles.
Architecture: Pre-generate a city_pairs table (city_a, city_b, distance_miles) for cities within 150 miles. Route is SSR; pulls data for both cities in one D1 query.
Scale: ~50,000 pairs Γ 10 projects = 500,000 potential pages. Crawl only major pairs first; use <meta name="robots" content="noindex"> on long-tail pairs until they earn organic traffic.
B. County Hub Pages
/county/{state}/{county-slug}/
Example: /county/il/cook-county/
Content: All cities in the county, permit activity trend, most popular project in the county (by permit volume), cost range across the county.
Architecture: Group zips by county, aggregate cost_multiplier range and permit data. SSR query. ~3,100 US counties Γ 10 projects possible, start with state hub pages linking to county hubs.
C. Best Time to Remodel Pages
/when-to/{project}/{state}/
Example: /when-to/roofing-costs/il/
Content: Month-by-month demand index chart for that state, booking window guidance, historical price seasonality, contractor availability narrative.
Architecture: Aggregate seasonal_adjustments by state (average across all climate zones in state). Static content per state Γ project = 500 pages.
D. Project Bundle Pages
/bundle/{project-a}-and-{project-b}/{zip}/
Example: /bundle/roofing-costs-and-hvac-replacement-costs/60601/
Content: Combined cost estimate, combined ROI rationale (bundling reduces contractor overhead), suggested sequencing. Pre-generate for the 15 highest-ROI project pairs only, for the top 500 ZIPs by traffic.
E. Contractor Cost Guide Pages (State Level)
/guide/{project}/{state}/
Example: /guide/roofing-costs/illinois/
Content: Full editorial guide β state licensing requirements, permit process, average contractor rates, what to include in a contract, red flags, recommended questions to ask. 1,000-2,000 words of genuine editorial content.
Scale: 10 projects Γ 50 states = 500 pages. These are link magnets. Write them properly.
2.6 Blog and Editorial Content Strategy
The blog is currently underused. This is your primary link magnet and E-E-A-T signal surface.
Content pillars:
Pillar 1: Annual Cost Reports (link magnets)
- "2026 State of Home Remodeling Costs" β publish annually in January
- "Most Expensive Cities for Kitchen Remodels in 2026" β city-level rankings
- "Where Roofing ROI Beats 100%: A ZIP-Code Analysis" β data journalism piece
- Each of these should be a standalone sharable URL with embedded tables and charts
Pillar 2: Project Deep Dives
- One 3,000-word definitive guide per project type
- Covers: what's included, what's not, how to read a bid, common upsells, DIY vs. hire
- These rank for head terms ("how much does a kitchen remodel cost") and link internally to ZIP pages
Pillar 3: Local Market Reports
- "Chicago Metro Remodeling Market β Q2 2026" (quarterly)
- Trigger: monthly cron job already exists; use it to generate market summary data and publish automated report stubs
Pillar 4: Homeowner Decision Guides
- "Should I Remodel or Sell? A ZIP-Code Calculator"
- "The Highest-ROI Projects in Your State Before Listing"
- "How to Time Your Remodel Around Interest Rate Cycles"
Publishing cadence:
- 2 pillar posts per month (manual, editorial quality)
- 4 local market reports per month (automated data + light editorial)
- 1 annual state of the industry report (January)
2.7 Internal Linking Upgrades
Add to every ZIP page:
- "Compare nearby markets" widget β 3 links to the same project in nearby cities (not ZIPs β city-level pages for broader appeal)
- "Other high-ROI projects in {city}" β ranks all 10 projects by ROI score for this ZIP, links top 3 to their respective ZIP pages
- "Trending in {county}" β links to the county hub page (to build once)
- Breadcrumb enhancement β add schema-aligned text breadcrumb visible on mobile: Home β Illinois β Cook County β Chicago β Roofing Costs
Project hub pages should link to:
- Top 10 metro ZIPs (by population) for that project
- All 50 state-level guide pages for that project
- The 3 most-linked blog posts for that project
State pages should link to:
- County hub pages
- Seasonal timing page for that state
- Top 5 cities by permit volume
Part 3: E-E-A-T and Entity Building
Google needs to trust the data. Right now the site has no named authors, no clear methodology, and no press presence. These are fixable.
3.1 Methodology Page
Build /methodology/ β a detailed explanation of:
- Where cost data comes from (Zillow ZHVI, Remodeling Magazine Cost vs. Value, Census permit data)
- How cost multipliers are calculated (regression model, inputs, update frequency)
- How ROI scores are computed (formula, data sources, limitations)
- How seasonal data is sourced (NOAA climate zones, contractor survey data if applicable)
- Accuracy disclaimer and confidence intervals
This page should be linked in the footer of every page. Journalists and bloggers linking to your data will link here too.
3.2 Author Profiles
Create /team/ or /about/ with named contributors. If you are the sole operator, a founder profile with LinkedIn link, professional photo, and domain expertise statement is enough.
Add author schema to all blog posts pointing to the author's profile page.
3.3 Press / Media Page
Create /press/ listing any coverage the site has received. Even one mention earns a link here. This page signals legitimacy to both journalists and Google.
Include a "For press inquiries" section with a direct email. Journalists who want to cite your data need a clear point of contact.
3.4 Data Attribution and Sourcing
Every ZIP page currently credits "Cost vs. Value" data. Make this more prominent and linkable:
- Add a "Data Sources" section at the bottom of every ZIP page (small, not intrusive)
- Link to the Remodeling Magazine, Zillow, and Census Bureau directly
- These outbound links to authoritative sources are a trust signal
Part 4: External SEO β Link Building
Two categories: scalable/automated and manual/niche. Both are necessary.
4.1 Digital PR β Data Journalism (Highest ROI)
You have 260,000 data points across the US. That is a news asset. Local and national journalists need data stories.
Campaign 1: "Most Expensive Cities to Remodel β 2026"
- Extract the 50 most expensive and 50 cheapest cities per project from D1
- Format as a ranked list with methodology
- Write a 500-word press release framing it as a housing affordability story
- Pitch to: Bankrate, NerdWallet, The Zebra, local TV news stations in the featured cities
- Expected yield: 5-15 links from DA 40-90 sites per campaign
Campaign 2: Local Market Angles
- For any city where cost_multiplier is at an extreme (very high or very low), pitch the local newspaper
- "Chicago homeowners pay 40% more for kitchen remodels than the national average β here's why"
- Pitch to the Chicago Tribune, Chicago Sun-Times, Crain's Chicago Business
- Every local paper in a major metro is a DA 50-80 link
- Do this for top 30 metros β that's 30 potential placements
Campaign 3: Real Estate Timing Angles
- Spring homebuying season (FebruaryβApril): "Which remodels have the best ROI before listing?"
- Fall: "Best remodeling projects for homeowners staying put this winter"
- Pitch to: Inman, RealTrends, HousingWire, local real estate blogs
Campaign 4: Economic Angle
- When Fed changes interest rates, pitch "How interest rates are changing which home improvements make sense"
- Your ROI data is evergreen; reframe it around news cycles
- Pitch to: MarketWatch, Business Insider Personal Finance, AP Real Estate
Execution cadence: One PR campaign per month. Build a media list of 200+ outlets (local papers in top 50 metros + national personal finance + real estate vertical). Use Hunter.io or Apollo to find journalist emails. Send personalized pitches (not blast emails).
4.2 HARO / Journalist Query Response
Sign up for:
- HARO (Help A Reporter Out) β respond to every query tagged home improvement, real estate, personal finance, housing
- Qwoted β similar platform, less competitive
- ProfNet β more PR-industry focused
Response strategy:
- Keep responses under 150 words
- Lead with a specific data point from your dataset
- Include your name, title (Founder, RemodelFinder), and a link to the relevant methodology or ZIP page
- Respond within 2 hours of the query appearing β speed matters on HARO
Expected yield: 1-3 links per month from DA 40-80 publications. Compounds over time.
4.3 Niche Manual Outreach
Real Estate Agent Networks
- Target: individual agent blogs, team websites, boutique brokerage resource pages
- Pitch: "Free remodeling cost tool for your clients β here's how to embed it or link to it"
- Value prop: agents want to give sellers renovation-ROI advice; your tool does it automatically
- Volume: 500 agents Γ 3% response rate = 15 links
- Find targets: Search "home remodeling cost [city]" β find agent blogs ranking β contact them
Home Inspector Blogs and Newsletters
- Home inspectors write extensively about what they find in homes
- They need cost data to help clients understand repair scopes
- Pitch: "Would your readers benefit from seeing local repair cost estimates?"
- Target: ASHI (American Society of Home Inspectors) member directories
- Find blogs: search "home inspection blog [state]"
Mortgage and Lending Sites
- Renovation loan content (203k, Fannie Mae HomeStyle) needs cost context
- Your ZIP-level data is exactly what a "how much can I borrow for my remodel" post needs
- Target: regional credit unions with blogs, mortgage broker sites, LendingTree content partners
- Pitch: "We have ZIP-level cost data that would make your renovation loan content more useful"
Interior Design and Architecture Blogs
- Bloggers who cover kitchen/bathroom renovations need cost context
- Pitch a content swap: they embed your cost widget or link to your project guide; you mention them
- Target: Houzz contributors, apartment therapy contributors, design bloggers with DA 30+
- Find via: BuzzSumo search for "kitchen remodel cost" β top shared content = active linkers
HOA Management Companies
- HOA newsletters and blogs advise homeowners on property improvements
- Your ROI data and cost estimates are directly relevant
- Pitch: "Free resource for your homeowners on which improvements add value in your community"
- Target: FirstService Residential, Association Management Group, CINC Systems blog
Contractor Associations
- NAHB (National Association of Home Builders) β DA 75+, very hard but worth attempting
- NARI (National Association of the Remodeling Industry) β industry trade, DA 60
- State-level contractor licensing associations
- Pitch: Data partnership β they share your cost data with members, you link to their association on your methodology page
Real Estate Investment Forums and Blogs
- Bigger Pockets (DA 80+) β contribute to their forums with data; link naturally in expert answers
- REI-focused Facebook groups and newsletters
- Landlord blogs (landlords need renovation cost data for Section 8 compliance, deferred maintenance budgets)
University Extension Programs
- Land-grant university extension offices publish housing guides for homeowners
- UMass Extension, Ohio State Extension, Texas A&M AgriLife all have housing content
- Pitch: "We have free ZIP-level cost data that would enhance your homeowner guides"
- These are DA 80-95 links from .edu domains β very high value
4.4 Link Magnets β Assets Built for Acquisition
These are pages you build specifically to earn links, not just to rank.
A. Embeddable Cost Widget
Build a JavaScript embed (3-5 lines of code) that any real estate agent, contractor, or blogger can paste into their site. The widget shows a ZIP code input that pulls and displays the local cost estimate for one project.
<script src="https://remodelfinder.com/widget.js"
data-project="roofing-costs"
data-theme="light"></script>
When a site embeds the widget, they naturally link back. Target 1,000 embeds = 1,000 referring domains.
Pitch it to:
- Real estate agent websites
- Contractor websites
- Personal finance bloggers
- Local news sites (they love interactive tools)
B. Free API for Researchers and Journalists
Offer a rate-limited free API tier (1,000 requests/day) for journalists, researchers, and non-commercial use. Require attribution in the terms.
GET https://api.remodelfinder.com/estimate?project=roofing&zip=60601
Every academic paper, journalist article, or research report that uses your data must cite your API β which means a link.
C. Annual "Cost vs. Value" Report
Each January, publish a full data report:
- National cost trends year-over-year
- State-by-state rankings
- Top 10 ROI improvements nationally
- Methodology notes
Format it as a proper report (PDF + landing page). Submit to:
- NAHB research library
- Harvard Joint Center for Housing Studies
- Urban Land Institute
- Remodeling Magazine (they publish the underlying data β a competitor collab is possible)
D. Interactive State Maps
Build a /map/{project}/ page showing a choropleth map of cost multipliers by state. Journalists love maps β they are inherently embeddable and shareable.
Libraries: Use Leaflet.js or D3 with Cloudflare KV-cached GeoJSON. Embed code provided below the map.
4.5 Competitor Link Gap Analysis
Run this immediately:
- Pull backlink profiles from: Homewyse.com, Fixr.com, Angi.com, HomeAdvisor.com, Thumbtack.com
- Tools: Ahrefs, Semrush, or Moz (one-time pull)
- Find domains linking to 2+ competitors but not to RemodelFinder
- These are pre-qualified prospects β they already link to cost data sites
This analysis typically surfaces 200-500 high-quality prospects within a few hours.
Common link sources that competitors have:
- State government consumer protection pages linking to "get contractor estimates"
- Personal finance resource pages ("tools for homeowners")
- Real estate school curriculum pages
- First-time homebuyer guides at credit unions and banks
4.6 Directory and Citation Building
Not glamorous but provides link diversity and local trust signals.
Tier 1 (get these first):
- Product Hunt listing (DA 91) β submit as a free tool for homeowners
- Futurepedia / AI tool directories (DA 50+) β submit as an AI-enhanced cost estimator
- Crunchbase β create a company profile (DA 92)
- LinkedIn Company Page β fills entity knowledge graph
- G2 / Capterra β list as a free consumer tool
Tier 2:
- Yelp Business Profile
- Better Business Bureau
- Local chamber of commerce listings for your business location
Tier 3 (niche directories):
- Houzz Pro resource section
- Fixr editorial links (competitor but cross-links happen)
- Remodeling Magazine online resource links
- BuildZoom blog references
4.7 Community and Forum Presence
Reddit:
- r/HomeImprovement (3.2M members) β answer questions about project costs with specific ZIP-level data. Never spam; provide genuine value. After 3-6 months of legitimate participation, users will link to your tool organically.
- r/RealEstate, r/FirstTimeHomeBuyer β similar approach
- Do not post affiliate-style links. Post data-driven answers and let the URL speak for itself.
Quora:
- Write detailed answers to "How much does a kitchen remodel cost in Chicago?" type questions
- Include your methodology and link to the specific ZIP page
- These answers rank in Google independently (Quora is DA 93)
Facebook Groups:
- Local homeowner groups in major metros
- Nextdoor via a "business" presence
- These are lower-quality links but drive direct traffic which signals engagement to Google
Part 5: Indexation Acceleration Strategy
Getting 71,000 pages indexed requires both authority and crawl budget. Here is the prioritized approach.
5.1 Indexation Priority Tiers
Tier 1 β Index immediately (top 5,000 pages):
- All ZIPs in the top 50 CBSAs by population
- For all 10 projects
- These ZIPs have the highest search volume, earn links first, and lift domain authority
Tier 2 β Index within 6 months:
- All ZIPs in states with highest remodeling spend (CA, TX, FL, NY, IL, PA, OH)
- All city hub pages for cities with 50,000+ population
Tier 3 β Index over 12-24 months:
- Remaining ZIPs as crawl budget grows with domain authority
5.2 Forcing Indexation for Tier 1
- Submit Tier 1 ZIPs via Google Search Console URL Inspection β Request Indexing (bulk tool via API)
- Use Google's Indexing API for programmatic submission (originally for job postings but works for any pages in practice)
- Ensure every Tier 1 ZIP is reachable within 3 clicks from the homepage through internal links
- Create a "Popular Markets" section on the homepage with direct links to the top 50 metro ZIPs
5.3 Internal Link Depth Audit
Run a crawl simulation to verify no ZIP page is more than 4 clicks from the homepage:
Homepage β State Page β City Page β ZIP Page (3 clicks β good)
The sitemaps handle crawl discovery, but Google also follows internal links for authority distribution. Verify that the sitemap β indexation pipeline is working by checking Search Console "Coverage" report weekly.
Part 6: Measurement and KPIs
6.1 Weekly Metrics
| Metric |
Source |
Target |
| Pages indexed |
Search Console Coverage |
+500/week until fully indexed |
| Sitemap fetch errors |
Search Console Sitemaps |
0 |
| Core Web Vitals pass rate |
Search Console CWV |
>90% |
| Average position (all pages) |
Search Console Performance |
Track week-over-week |
| Clicks from organic |
Search Console |
Track week-over-week |
6.2 Monthly Metrics
| Metric |
Source |
Target |
| Referring domains |
Ahrefs/Semrush |
+20/month minimum |
| New backlinks |
Ahrefs/Semrush |
+100/month |
| DA / DR growth |
Ahrefs/Semrush |
+2 points/quarter |
| HARO responses |
Manual log |
20/month |
| PR placements |
Manual log |
1/month |
| Blog posts published |
CMS |
6/month |
6.3 Quarterly Reviews
- Full content differentiation audit: sample 100 ZIP pages across 5 projects, score prose uniqueness
- Competitor rank tracking: pull top 20 competitors for "roofing costs [city]" across 10 cities
- Link gap analysis refresh: new competitor backlinks since last quarter
- Indexation rate review: indexed vs. discovered pages ratio trend
Part 7: Execution Sequence
Work in this order. Each phase unlocks the next.
Phase 1 β Foundation (Weeks 1-4)
Phase 2 β Content Differentiation (Weeks 5-10)
Phase 3 β New Page Types (Weeks 8-14)
Phase 4 β Digital PR (Ongoing from Week 3)
Phase 5 β Niche Outreach (Weeks 8-20)
Phase 6 β Scale (Month 6+)
Rollout Status
| Phase |
Work |
Status |
Notes |
| Bug fix |
Template literal URL in zip-banner JS |
DONE |
Fixed with DOM manipulation instead of innerHTML |
| Phase 1 |
Fix <lastmod> in sitemaps |
DONE |
Pinned DATA_VERSION = '2025-10-01' constant across all 4 sitemap files. Bump when cost/ROI data is refreshed. |
| Phase 1 |
noindex prop infrastructure |
DONE |
Meta.astro + MainLayout.astro β pass noindex={true} to exclude any page |
| Phase 1 |
noindex for non-residential ZIPs |
DONE |
zip_type column on zips table + migrate_zip_type.sql applied locally. Applied to [zip].astro via noindex={zip.zip_type !== 'STANDARD'}. Populate non-STANDARD rows by downloading simplemaps free CSV to scripts/data/uszips.csv then running node scripts/build-zip-types.mjs. |
| Phase 1 |
Build /methodology/ page |
DONE |
E-E-A-T page: data sources, calculation walkthrough, limitations, FAQ |
| Phase 1 |
Create /about/ page |
DONE |
Project grid + contact CTA |
| Phase 1 |
Indexing API submission script |
DONE |
scripts/submit-indexing-api.mjs. Needs scripts/gsc-key.json (Google Cloud service account). Run --dry-run first. |
| Phase 1 |
Google Search Console baseline |
YOU |
Free. Connect GSC to the site, capture impression/click baseline before Phase 2 goes live remotely. |
| Phase 1 |
Sign up for HARO / Qwoted |
YOU |
helpareporter.com + qwoted.com. Aim for 20 responses/month. |
| Phase 1 |
Product Hunt + Crunchbase |
YOU |
One-time. DA 91 backlink from Product Hunt. |
| Phase 2 |
Climate-aware prose variation |
DONE |
5 climate groups Γ 10 projects, unique scope/decisions/timing copy |
| Phase 2 |
Expanded FAQ bank + selection logic |
DONE |
4-6 FAQs per page from conditional bank (climate, ROI, demand, cost) |
| Phase 2 |
10 project deep-dive guides |
DONE |
/guides/{slug}/ Γ 10 + index. In sitemap. |
| Phase 2 |
D1 schema: zip_demographics, zip_risk_zones, state_regulations |
DONE |
scripts/migrate_phase2.sql β applied locally. Apply remotely before next deploy. |
| Phase 2 |
zip_type migration |
DONE |
scripts/migrate_zip_type.sql β applied locally. Apply remotely before next deploy. |
| Phase 2 |
Census ACS demographics pipeline |
DONE |
scripts/build-demographics.mjs. 26,273 rows loaded locally. .env holds CENSUS_API_KEY. |
| Phase 2 |
FEMA/NOAA risk zones pipeline |
DONE |
scripts/build-risk-zones.mjs. 26,283 rows loaded locally. FEMA API fell back to coastal-state heuristic. |
| Phase 2 |
Wire demographics + risk zones into [zip].astro |
DONE |
5 parallel D1 queries. housingAgeTier, densityTier, hailRiskTier, inSfha, isWui passed to content context. |
| Phase 2 |
Housing-age + risk-zone copy variation in projectContent.ts |
DONE |
Pre-war/postwar/WUI/SFHA/hail variations for roofing, siding, HVAC, deck, basement. |
| Phase 3 |
State guide pages (/guide/{project}/{state}/) |
NEXT |
500 pages. Start here next session. |
| Phase 3 |
County pages (/county/{state}/{county}/) |
Pending |
|
| Phase 3 |
Timing pages (/when-to/{project}/{state}/) |
Pending |
|
| Phase 3 |
Embeddable widget |
Pending |
|
| Phase 4 |
"Most Expensive Cities to Remodel 2026" PR report |
Pending |
|
| Phase 4 |
Pitch to Bankrate, NerdWallet, local papers |
Pending |
|
| Phase 4 |
HARO response cadence |
Pending |
|
| Phase 5 |
Competitor backlink gap + outreach |
Pending |
|
| Phase 6 |
Free API, state maps, annual report |
Pending |
|
Next Session β Checklist
Work through this top to bottom.
1. Apply remote DB migrations (before deploying)
All Phase 2 data is local only. Apply to the remote D1 before the next deploy:
# Phase 2 tables (demographics, risk_zones, state_regulations)
npx wrangler d1 execute remodelfinder-db --remote --file=scripts/migrate_phase2.sql
# zip_type column
npx wrangler d1 execute remodelfinder-db --remote --file=scripts/migrate_zip_type.sql
# Risk zone data (6 MB, under D1 10 MB limit)
npx wrangler d1 execute remodelfinder-db --remote --file=scripts/data/risk_zones.sql
# Demographics data (9.3 MB, just under limit β may need to split if it fails)
npx wrangler d1 execute remodelfinder-db --remote --file=scripts/data/demographics.sql
# If that fails due to size, split and retry:
# split -l 4000 scripts/data/demographics.sql demo_chunk_
# for f in demo_chunk_*; do npx wrangler d1 execute remodelfinder-db --remote --file="$f"; done
2. Populate non-standard ZIP types (optional, low priority)
Non-residential ZIPs get noindex automatically, but only when the zip_type column is populated. Right now everything defaults to STANDARD. To populate:
- Download free ZIP database from simplemaps.com/data/us-zips
- Save as
scripts/data/uszips.csv
- Run
node scripts/build-zip-types.mjs β generates scripts/data/zip_types.sql
- Apply:
npx wrangler d1 execute remodelfinder-db --remote --file=scripts/data/zip_types.sql
3. Set up Google Indexing API (for Phase 1 submission script)
- Go to console.cloud.google.com
- Create a project (or use existing)
- Enable the "Web Search Indexing API"
- Create a service account, download the JSON key
- Save key as
scripts/gsc-key.json (already gitignored via scripts/data/)
- Add the service account email as an owner in Google Search Console
- Run:
node scripts/submit-indexing-api.mjs --dry-run to preview
- Run without
--dry-run to submit top ~500 URLs to Google
4. Phase 3 β State guide pages (next engineering task)
This is where to start next time for new pages:
What: One page per project Γ state = 500 pages at /guide/{project}/{state}/
Example: /guide/roofing/california/
Why: State-level pages target mid-funnel queries like "roof replacement cost California" β lower competition than national terms, higher than ZIP-level.
Architecture:
- Static generation (prerender=true), built at deploy time from a
[project]/[state].astro route
- Pull state-level cost averages from D1 (aggregate of ZIP rows for that state)
- Pull
state_regulations row for energy code, licensing, HOA context
- Reuse
projectContent.ts climate + regulation signals
- Add a "Top cities in {state}" table linking to the 5 highest-traffic ZIPs
Data already in place: state_regulations table has 20 states seeded. The other 30 need data β fill them in migrate_phase2.sql or a separate migration before building the pages.
Start here: src/pages/guide/[project]/[state].astro