Library batch 2: plays 05-08, completing the Keyword Research library (#187)
This commit is contained in:
parent
d2d8f7e19a
commit
85095f4ac6
@ -79,6 +79,7 @@ Run these before delivering any prose:
|
||||
- Any sentence starting with What/When/Where/Which/Who/Why/How as a crutch? Restructure.
|
||||
- Meta-joiners ("The rest of this essay...")? Delete.
|
||||
- "It's worth noting" or similar filler transitions? Delete.
|
||||
- Any self-certifying "honest answer/framing/signal" language? State the evidence, limit, or uncertainty instead.
|
||||
- Same metaphor used more than twice? Replace or cut repeats.
|
||||
- "Despite these challenges..." formula? Rewrite.
|
||||
- Bold-first bullet pattern? Remove bold leads.
|
||||
|
||||
@ -187,6 +187,25 @@ Asserting clarity instead of demonstrating it:
|
||||
- "History is clear, the metrics are clear, the examples are clear"
|
||||
- "but none of them is the real story. The real story is..."
|
||||
|
||||
## Self-Certifying Candor
|
||||
|
||||
Avoid phrases that announce the writer's honesty instead of making the claim precise:
|
||||
|
||||
- "the honest answer"
|
||||
- "the honest framing"
|
||||
- "the most honest signal"
|
||||
- "an honest forecast"
|
||||
- "the truth is"
|
||||
|
||||
Do not mechanically replace "honest" with "realistic," "candid," or another unsupported self-certification such as "clearest" or "most reliable." State the evidence, limitation, or uncertainty directly. When a modifier is necessary, use one that names the basis of the claim: "first-party," "directional," "modeled," "bounded," or "based on stated assumptions." Keep ordinary uses that describe a person's conduct or testimony, such as "she gave an honest account."
|
||||
|
||||
| Avoid | Use instead |
|
||||
|-------|-------------|
|
||||
| "The honest framing is that ranking and traffic have come apart." | "Ranking and traffic have come apart." |
|
||||
| "The honest answer lives between the scenarios." | "The likely outcome falls between the scenarios." |
|
||||
| "This is the most honest signal available." | "Treat this as a directional signal, not direct attribution." |
|
||||
| "Use an honest forecast." | "Build the forecast from stated assumptions." |
|
||||
|
||||
## Vague Declaratives
|
||||
|
||||
Sentences that announce importance without naming the specific thing. Kill these or replace with the specific thing.
|
||||
|
||||
@ -17,6 +17,7 @@ Everything we publish must be traceable to what the product actually does and co
|
||||
4. **Sound like a person.** Fix AI tells by restating the underlying claim plainly, not by polishing the flourish. The [deslop skill](../deslop/SKILL.md) is the reference for what to hunt and how to fix it.
|
||||
5. **Reader-first altitude.** Guides teach actionable SEO that stands on its own — not product documentation, not generic filler. Credit free resources to their real owners (Google's autocomplete, the reader's own Search Console).
|
||||
6. **One bar, whole surface.** When a standard improves, sweep everything to it — all the FAQs, all the pages — not just the instance that got noticed.
|
||||
7. **Playbook terminology.** Call each approach within any OpenSEO playbook a "strategy," never a "play." Use "workflow" for the steps readers execute; use "playbook" only for the complete collection.
|
||||
|
||||
## Questions to ask while reviewing
|
||||
|
||||
|
||||
@ -21,11 +21,11 @@ Keyword clustering is grouping keywords that deserve the _same page_ because the
|
||||
|
||||
Cannibalization is the opposite problem: two of your pages compete for one intent, Google alternates between them, and both rank worse than either would alone.
|
||||
|
||||
- **Find it:** in [Search Console](/google-search-console-mcp), group by query + page. Any query with 2+ of your URLs swapping impressions is a candidate.
|
||||
- **Find it:** in [Search Console](/google-search-console-mcp), group by query + page. Any query with 2+ of your URLs swapping impressions is a candidate. [Programmatic discovery](/library/keyword-research/gsc-programmatic-discovery) runs the same grouping across every page at once.
|
||||
- **Fix it:** merge the weaker page into the stronger (301), or re-point the weaker page at a genuinely different intent and re-title it.
|
||||
- **Prevent it:** the keyword map from step 5. No new page ships without checking which cluster it claims.
|
||||
|
||||
Run this play with the [OpenSEO MCP](/docs/mcp):
|
||||
Run this workflow with the [OpenSEO MCP](/docs/mcp):
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP + Search Console: pull my queries grouped by
|
||||
@ -46,4 +46,4 @@ Not an unlimited one. The grouping step itself is free (the MCP prompt above doe
|
||||
|
||||
### What is a keyword mapping template?
|
||||
|
||||
A sheet with one row per cluster: primary keyword, supporting keywords, intent, target URL, status. The keyword map above is the working example; copy the structure.
|
||||
A sheet with one row per cluster: primary keyword, supporting keywords, intent, target URL, status. The keyword map above is the working example; copy the structure. Add a forecast column and it becomes a build order: [size each cluster](/library/keyword-research/opportunity-sizing-forecasting) before you commit the quarter.
|
||||
|
||||
107
web/content/marketing/library/gsc-programmatic-discovery.mdx
Normal file
107
web/content/marketing/library/gsc-programmatic-discovery.mdx
Normal file
@ -0,0 +1,107 @@
|
||||
---
|
||||
title: "Query-mine the Search Console you already own"
|
||||
description: "Your own Search Console is the only keyword database built from people who reached you. The strategy for mining it: striking-distance keywords, zero-click pages, and the queries Google won't name."
|
||||
---
|
||||
|
||||
## What is programmatic keyword discovery?
|
||||
|
||||
Programmatic keyword discovery means treating your own Search Console as the keyword database, then working it in bulk instead of one query at a time. Every other source estimates demand from the outside. Search Console reports demand that already found you, on the pages that already exist, with the positions you already hold. It is the only first-party keyword data you own, and most sites read maybe two screens of it a month.
|
||||
|
||||
The catch is that Google hands it to you in a shape designed for spot checks rather than strategy. Working it programmatically means pulling the whole surface through an API, joining it to your rankings, and asking questions the interface will not answer.
|
||||
|
||||
## Why your query report is missing most of your clicks
|
||||
|
||||
Open a page report and note the click total. Then add up the clicks in the query table underneath. The second number is smaller, often dramatically so. Google anonymizes queries below a privacy threshold, so the searches that drove most of your traffic never appear by name.
|
||||
|
||||
The gap is worse than most people assume. On one of my own pages earning around a hundred clicks a month, the interface named five queries. Going through the API raised that to twelve. Out of a hundred clicks, I could name twelve of them, on a page I wrote and understood.
|
||||
|
||||
That is the problem the [dark query post](/blogs/dark-queries) works through in detail. This page is the repeatable strategy that comes out of it.
|
||||
|
||||
Grant Simmons, who has built SEO tooling for years, adds a confidence score to his estimates:
|
||||
|
||||
> Most of my tools, I add in a confidence score, because the math is just math and reasoning is just reasoning.
|
||||
|
||||
He is also skeptical that the gap can be closed outright, on the grounds that you are still dealing with garbage in and garbage out. Both things hold. You cannot recover the exact hidden queries, and you can still assemble a defensible picture of them from data you already hold.
|
||||
|
||||
## How to find striking-distance keywords in Search Console
|
||||
|
||||
Striking-distance keywords are the terms where you rank between roughly position 11 and 30. They earn few clicks and prove Google already considers your page a credible answer. Moving one of them onto page one is cheaper than earning a new ranking from nothing, which makes this the highest-return query mine on most sites.
|
||||
|
||||
The workflow runs in four steps:
|
||||
|
||||
1. Pull every query for the property over the longest window available, not the default three months.
|
||||
2. Filter to positions 11 to 30 with impressions above your own noise floor.
|
||||
3. Group those queries by the page currently ranking, which turns a keyword list into a page-by-page work queue.
|
||||
4. Sort each page's group by impressions, because impressions measure demand that Google is already showing you losing.
|
||||
|
||||

|
||||
|
||||
The list above is one site's striking-distance band, filtered to positions 10 through 13. Nothing here is a head term, and that is the point: these are queries the site already half-ranks for, several of them worth a few hundred searches a month, all of them sitting one page away from traffic.
|
||||
|
||||
Step three matters more than it looks. Sorting by query treats every row as its own project. Grouping by page tells you which single URL to improve to capture a dozen of them at once, which is the same logic behind [clustering keywords into topical hubs](/library/keyword-research/cluster-topical-hubs).
|
||||
|
||||
## The 16-month window most people skip
|
||||
|
||||
Search Console's default view is short, and the export most people take is shorter. Grant's practical advice is to stop working from the recent slice:
|
||||
|
||||
> Generally you get a lot more information when you look at the 16 months of Google Search Console data, to have an understanding of, if the article has been around for that long, all the queries that have mapped, not just the most recent queries. I think that's often forgotten.
|
||||
|
||||
Sixteen months is the full retention window Google offers. Pulling all of it changes what you can see: seasonal queries that vanish from a 90-day view, terms a page ranked for before a redesign, and the slow drift of a page away from the topic it was written for. A query that appeared for six months and stopped is a signal. A 90-day export shows you an absence instead.
|
||||
|
||||
## Zero-click pages and the queries worth rewriting for
|
||||
|
||||
The other half of the mine runs in the opposite direction. Look for pages with heavy impressions and almost no clicks. High impressions confirm Google shows the page for real demand. Near-zero clicks means the title and description are losing the auction, or the page is answering an intent the searcher did not have.
|
||||
|
||||
Sort those by impressions and read the queries attached. When the queries do not match what the page is about, you have found a page drifting off its topic, and the fix is usually a split rather than a rewrite. When the queries match and the clicks still do not come, the fix is the title. Both are cheaper than new content, and both come from data you already own.
|
||||
|
||||
## Do it with OpenSEO
|
||||
|
||||
Because the Search Console connection runs through OpenSEO, your agent can query it alongside your ranking data without a second integration. Connect the [OpenSEO MCP](/docs/mcp) once, or read how the [Search Console MCP](/google-search-console-mcp) fits together, then run the workflow with this prompt.
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP, pull Search Console query data for
|
||||
[mydomain.com] over the longest window available.
|
||||
|
||||
1. Striking distance
|
||||
Filter to queries in positions 11-30 with more than [50] impressions.
|
||||
Group them by the page that ranks, then sort each group by total
|
||||
impressions. Give me the top 10 pages by recoverable impressions.
|
||||
|
||||
2. Zero-click pages
|
||||
List pages with high impressions and a click-through rate under 1%.
|
||||
For each, show the queries driving the impressions and tell me
|
||||
whether they match the page's actual topic.
|
||||
|
||||
3. The gap
|
||||
For my top 10 pages by clicks, compare total clicks against the sum
|
||||
of clicks in the named-query table. Report the difference as a
|
||||
percentage. Those are the pages where I am planning blind.
|
||||
|
||||
Output as a document I can review.
|
||||
```
|
||||
|
||||
The output is a work queue ordered by what it would cost to fix, rather than a keyword list ordered by a volume number that was never about your site.
|
||||
|
||||
## What to do first
|
||||
|
||||
Run step one against your single most important page. If the striking-distance group has more than five queries in it, that page is the next thing you should edit, and you now know which ten words to edit it around. Then widen the window to sixteen months and see what used to work.
|
||||
|
||||
From here, the queries you surface feed the rest of the library. Unnamed question queries belong in [long-tail question mining](/library/keyword-research/long-tail-question-mining). Grouped page queries belong in [topical hubs](/library/keyword-research/cluster-topical-hubs). Anything with buying language belongs in [intent mapping](/library/keyword-research/search-intent-mapping) before you write a word.
|
||||
|
||||
## Search Console keyword research FAQ
|
||||
|
||||
### Can you use Google Search Console for keyword research?
|
||||
|
||||
Yes, and it is the most reliable source you have, because it reports queries that reached your site rather than estimating a market. Its limits are that it only shows terms you already rank for, and it hides queries below a privacy threshold. Use it for expansion and validation, and use a keyword tool for the demand you have not captured yet.
|
||||
|
||||
### What are striking-distance keywords?
|
||||
|
||||
Queries where you rank roughly between positions 11 and 30. They sit on page two, earn few clicks, and demonstrate that Google already treats your page as a plausible answer. They are the cheapest rankings to improve on most sites.
|
||||
|
||||
### How far back does Google Search Console data go?
|
||||
|
||||
Sixteen months. Most exports default to a far shorter window, so pulling the full range surfaces seasonal queries and historical rankings that a 90-day view hides.
|
||||
|
||||
### Why don't the clicks in the query table add up to the total?
|
||||
|
||||
Google anonymizes queries that too few people searched, so they never appear by name while their clicks still count in the total. The shortfall runs from a small fraction to most of the total depending on the size of the site. Reading the same pages at page level rather than query level recovers much of the count.
|
||||
108
web/content/marketing/library/intent-beyond-google.mdx
Normal file
108
web/content/marketing/library/intent-beyond-google.mdx
Normal file
@ -0,0 +1,108 @@
|
||||
---
|
||||
title: "Where the queries happen when they don't happen in Google"
|
||||
description: "Pinterest, LinkedIn and the AI assistants all run on intent, and none of them appear in your keyword tool. The research method carries over; the surfaces do not."
|
||||
---
|
||||
|
||||
## Where does keyword research happen outside Google?
|
||||
|
||||
Keyword research assumes one box. A person types, an engine ranks, you measure the click. That model still describes a large share of demand, and it describes a shrinking share of discovery. People look things up inside Pinterest, inside LinkedIn, inside YouTube, and increasingly inside an assistant that answers without sending anyone anywhere.
|
||||
|
||||
The discipline transfers cleanly. You are still asking what somebody wants, in what words, at what stage. What changes is that these surfaces publish no volume data, so the research runs on the platform's own autocomplete, on your first-party results, and on the vocabulary your customers already use. That last source is the one that works everywhere, which is why [seeding from conversation](/library/keyword-research/seed-from-conversation) matters more here than on Google.
|
||||
|
||||
## Pinterest is a search engine wearing a social network's clothes
|
||||
|
||||
Julia Bocchese works almost entirely in Pinterest and SEO, and she is direct about why the two belong together:
|
||||
|
||||
> Most of the time when people go to Pinterest, they are searching for something. They're not really going there to follow people or to comment on pins. They're really searching for information, ideas, inspiration, products.
|
||||
|
||||
That single observation changes what you optimize. On a social network, the account is the unit and the follower is the asset. On a search surface, the query is the unit, and Julia points out the practical consequence: the audience arriving from a Pinterest search has no idea who you are.
|
||||
|
||||
> People aren't going on Pinterest to follow people. They're searching for information. So they likely don't know who you are.
|
||||
|
||||
The optimization work looks familiar as a result. Keywords belong in pin titles, in pin descriptions, in the text rendered on the graphic itself, and in the board and profile copy, because the platform has to understand the account and the pin before it can match either to a search. It is the same two-sided job as a page title and a site structure, run on a surface with no Search Console.
|
||||
|
||||
## LinkedIn ranks the profile, not the post
|
||||
|
||||
Daniel Alfon makes an argument that sounds wrong until you check your own behaviour on the platform:
|
||||
|
||||
> LinkedIn is the only platform where, Jeremy, you can be successful without posting content. That's amazing. Because if you want to be a successful YouTube or Instagram or TikTok, you have to upload content.
|
||||
|
||||
His reasoning is that the most common action on LinkedIn is visiting somebody's profile. The profile is therefore the ranked, keyword-sensitive asset, and the question a visitor arrives with is narrow: is your specialty the specialty they are looking for. His advice follows from that. Take care of the profile, make sure it converts, and treat posting as the secondary activity it is.
|
||||
|
||||
For keyword work this means the headline and the about section carry the load a title tag carries elsewhere. They should contain the words a stranger would use to describe the problem you solve, not the internal job title your company assigns you.
|
||||
|
||||
## The assistants answer, and the click never arrives
|
||||
|
||||
The third surface is changing fastest: ranking and traffic have come apart. Christopher Gimmer, running a site with a decade of authority behind it, describes the split:
|
||||
|
||||
> Even though we're ranking number one for some of these keywords, the AI Overviews are answering some of those things, and so we're losing out on some of those clicks.
|
||||
|
||||
He adds a second erosion that has nothing to do with AI. On commercial queries the paid block has grown to the point where position one is not position one on the page:
|
||||
|
||||
> Even if you're ranking number one for that organic keyword, your link is actually the fifth one on the page. And if you're ranking number three, you're now like eight links down.
|
||||
|
||||

|
||||
|
||||
The intent column is the closest native proxy for this. The rows labelled informational are the ones an assistant can satisfy without sending anyone anywhere, and the transactional and commercial rows are the ones that still end in a visit. Reading the list that way tells you which part of your research is exposed to the answer layer before you commit to any of it.
|
||||
|
||||
Two lessons for research. First, rank is a weaker proxy for traffic than it used to be, which is why [forecasting](/library/keyword-research/opportunity-sizing-forecasting) should apply a CTR curve that reflects the SERP you face rather than a textbook one. Second, informational queries that an assistant can satisfy in a paragraph are worth less than they look in a volume column, and queries requiring a tool, a login, a price or a human are worth more.
|
||||
|
||||
## How to research a surface that publishes no volume data
|
||||
|
||||
None of these platforms will hand you a search volume. The method that works without one:
|
||||
|
||||
1. Type your seed into the platform's own search box and record the autocomplete suggestions. That list is the platform telling you what people search there.
|
||||
2. Read the top results and note the vocabulary they use in titles and opening lines, which is the language the platform has already rewarded.
|
||||
3. Check your own first-party data for the platform, where it exists, before trusting any of the above.
|
||||
4. Look for the branded lift. Discovery on a platform with no outbound links often shows up later as somebody searching your name in Google, which is the one measurable bridge back.
|
||||
|
||||
Point four is the measurement most people skip. If a platform sends no clicks, watch whether branded search grows while you invest there. It is a directional signal you can monitor in [your own Search Console](/library/keyword-research/gsc-programmatic-discovery).
|
||||
|
||||
## Do it with OpenSEO
|
||||
|
||||
The keyword work still needs a demand baseline, and Google remains the best available proxy for what people want even when they ask somewhere else.
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP, research keywords for "[my topic]" and label
|
||||
each result by intent.
|
||||
|
||||
1. Split by surface
|
||||
Flag which of these queries an AI assistant can fully answer in a
|
||||
paragraph, and which need a tool, a price, a login or a human. Rank
|
||||
the second group higher: those are the queries that still produce a
|
||||
visit.
|
||||
|
||||
2. Branded baseline
|
||||
Pull my branded queries and their trend over the last 12 months. I am
|
||||
going to invest in [platform], which sends no referral data, so I want
|
||||
the branded line as my before-picture.
|
||||
|
||||
3. Vocabulary
|
||||
For my top 10 non-branded queries, give me the phrasings a person
|
||||
would use searching inside Pinterest or LinkedIn rather than Google:
|
||||
shorter, more visual, more role-based.
|
||||
|
||||
Output as a document I can review.
|
||||
```
|
||||
|
||||
## What to do first
|
||||
|
||||
Take one seed and run it through the search box of whichever platform your customers use. Compare that autocomplete list against the keyword list you already have. The overlap tells you what carries across surfaces. The gap is the demand your current research has never seen, and it is usually phrased in words no keyword database would have suggested.
|
||||
|
||||
## Keyword research beyond Google FAQ
|
||||
|
||||
### How do you do keyword research for Pinterest?
|
||||
|
||||
Use the platform's own search box and its guided-search suggestions, then place those terms in pin titles, pin descriptions, the text on the image, and your board and profile copy. Pinterest has to understand the account and the pin before it can match either to a query, so both levels need the vocabulary.
|
||||
|
||||
### Does SEO work for LinkedIn profiles?
|
||||
|
||||
Yes, and the profile matters more than the posting. The most frequent action on the platform is viewing a profile, so the headline and about section carry the weight a title tag carries on a website. Write them in the words a stranger would use for the problem you solve.
|
||||
|
||||
### How do you optimize for AI assistants?
|
||||
|
||||
Answer questions directly and completely enough to be quotable, and accept that queries an assistant can satisfy in a paragraph will return fewer clicks regardless of your rank. Weight your research toward queries needing a tool, a price, a login or a person, because those still send a visit.
|
||||
|
||||
### How do you measure traffic from platforms that send no referral data?
|
||||
|
||||
Watch branded search. Discovery on a closed platform tends to surface later as people searching your name, so a rising branded line in Search Console during a campaign is a useful directional signal.
|
||||
@ -20,12 +20,12 @@ A short-tail query is an audience; a long-tail query is a person with a problem.
|
||||
## How to find long-tail keywords (3 free methods)
|
||||
|
||||
1. **Mine People Also Ask + autocomplete fan-out.** Type your head term, harvest every PAA question, then re-search each question and harvest again. Two levels deep gives you 30–50 real questions people ask.
|
||||
2. **Pull your own Search Console queries.** Your GSC data is a long-tail generator that no tool can match. Filter [queries with impressions but no clicks](/blogs/dark-queries): those are tails you already half-rank for.
|
||||
2. **Pull your own Search Console queries.** Your GSC data is a long-tail generator that no tool can match. Filter [queries with impressions but no clicks](/blogs/dark-queries): those are tails you already half-rank for. The full strategy for working that data in bulk is [programmatic discovery with Search Console](/library/keyword-research/gsc-programmatic-discovery).
|
||||
3. **Expand seeds in OpenSEO.** Feed your [seed list](/library/keyword-research/seed-from-conversation) into [keyword research](/features/keyword-research) and keep the specific, question-form results with clear intent regardless of volume. "0 volume" queries are measured, not dead.
|
||||
|
||||

|
||||
|
||||
Run this play with the [OpenSEO MCP](/docs/mcp):
|
||||
Run this workflow with the [OpenSEO MCP](/docs/mcp):
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP: research keywords for the seed "[your topic]",
|
||||
|
||||
@ -0,0 +1,97 @@
|
||||
---
|
||||
title: "Size the opportunity before you commit the quarter"
|
||||
description: "SEO forecasting turns a keyword cluster into a defensible traffic and revenue range, so you can argue for the work in the only two numbers a business treats as exact."
|
||||
---
|
||||
|
||||
## What is SEO forecasting?
|
||||
|
||||
SEO forecasting estimates the traffic and revenue a keyword cluster could return, before you spend anything building for it. The output is a range rather than a number, because every input is an estimate and pretending otherwise is how forecasts lose credibility on contact with reality.
|
||||
|
||||
The arithmetic is short. Take the combined search volume for a cluster, apply a click-through-rate curve for the position you expect to reach, apply your conversion rate, then apply the value of a conversion. Present the result as three scenarios rather than one figure. Conservative assumes position eight and your worst converting month. Aggressive assumes position three and your best. Build the middle scenario from your typical conversion rate and the position you expect to reach.
|
||||
|
||||
## How to size a keyword cluster before you invest
|
||||
|
||||
Sizing runs on the cluster, not on the keyword. A single term tells you nothing about the page you would build, because the page will rank for dozens of variations. [Clustering first](/library/keyword-research/cluster-topical-hubs) gives you a unit worth forecasting.
|
||||
|
||||
For each cluster, gather four inputs:
|
||||
|
||||
1. Combined monthly volume across every keyword in the cluster.
|
||||
2. The difficulty of the terms you would need to beat, which sets how long the climb takes.
|
||||
3. Your realistic ceiling position, judged from what already ranks and what you can credibly publish.
|
||||
4. The conversion value, taken from your own analytics rather than an industry average.
|
||||
|
||||
Difficulty deserves more weight than it usually gets. A cluster worth 5,000 searches a month behind a wall of established domains is worth less than a 400-search cluster nobody has bothered to answer, because you will reach the second one this quarter and the first one never. That comparison is the entire point of sizing.
|
||||
|
||||
## Why volume is the wrong number to lead with
|
||||
|
||||
Sorting by volume selects for the terms your competitors have already spent years defending. It also selects against the terms that convert. The pattern repeats across niches: the highest-volume keyword in a market is usually informational, and the terms carrying real buying intent sit an order of magnitude below it.
|
||||
|
||||

|
||||
|
||||
OpenSEO keeps volume and difficulty separate because they answer different questions. In the run above, the 10-search term has a difficulty score of 28, while the 6,600-search term scores 15. Neither number establishes value on its own. Use an expected rank, click-through rate, conversion rate, and conversion value to compare the business case instead of treating volume or difficulty as an opportunity score.
|
||||
|
||||
Paul Baterina ran the test that shows what disciplined sizing buys you. Working on long-tail category pages, he built a proper control group rather than shipping on instinct:
|
||||
|
||||
> We're four weeks in, we're seeing a 25% lift on the test group versus the control group. The control group is actually down 5%. So that's already a signal that I could roll this out to all the long tail pages, which we have about 40,000 of those.
|
||||
|
||||
Four weeks and one controlled test turned a guess about 40,000 pages into a decision with evidence under it. That is what a forecast is for. It is not a promise about traffic, it is a way to find out whether the bet is worth placing at scale.
|
||||
|
||||
## Report in the numbers the business already trusts
|
||||
|
||||
Traffic is the number SEOs reach for and the number executives discount, because it does not appear on any statement they are accountable for. Ernesto Ortiz puts the problem at the level of measurement rather than tactics:
|
||||
|
||||
> You've used it as a proxy for so long. You've got to have better metrics, and you need to have a clear way to evaluate business results.
|
||||
|
||||
Forecast in sessions if that is all you have, then translate. A cluster forecast that ends at "an estimated 900 sessions a month" invites a shrug. The same forecast carried through a 2% conversion rate and a $400 average order value ends at a number that gets a budget approved or rejected on its merits, which is the outcome you want either way.
|
||||
|
||||
The same arithmetic works in reverse for pages you already own. Take your current position, apply the CTR curve for position three, and the difference is the traffic your existing rankings are leaving on the table. That figure is often larger than anything new content would produce, and it is cheaper to capture. [Search Console discovery](/library/keyword-research/gsc-programmatic-discovery) finds those pages.
|
||||
|
||||
## Do it with OpenSEO
|
||||
|
||||
Connect the [OpenSEO MCP](/docs/mcp) and the sizing runs against live difficulty and volume data instead of a stale export.
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP, research keywords for "[my topic]" and cluster
|
||||
the results by intent.
|
||||
|
||||
1. Size each cluster
|
||||
For every cluster, report combined monthly volume, median keyword
|
||||
difficulty, and the domains currently holding the top 3. Flag any
|
||||
cluster where the top 3 are all sites I cannot realistically outrank.
|
||||
|
||||
2. Forecast a range
|
||||
For the 5 most winnable clusters, model traffic at position 3,
|
||||
position 5 and position 8 using a standard CTR curve. Show me
|
||||
conservative, moderate and aggressive scenarios.
|
||||
|
||||
3. Convert to money
|
||||
Apply a [2]% conversion rate and a [$400] conversion value to each
|
||||
scenario. Rank the clusters by moderate-scenario revenue per unit of
|
||||
difficulty, not by volume.
|
||||
|
||||
Output as a document I can review.
|
||||
```
|
||||
|
||||
Ranking by revenue per unit of difficulty is the step that changes the plan. It routinely promotes a cluster sitting eighth by volume to first by value, which is the whole argument the rest of this library makes.
|
||||
|
||||
## What to do first
|
||||
|
||||
Take the cluster you were about to write for and run the three scenarios against it. Then run them against one cluster you dismissed for having low volume. If the low-volume cluster wins on revenue per unit of difficulty, you have found the order your content calendar should have been in.
|
||||
|
||||
## SEO forecasting FAQ
|
||||
|
||||
### How accurate is SEO forecasting?
|
||||
|
||||
Directionally useful and precisely wrong, which is why the output should be a range. Volume figures are estimates, CTR curves are averages across wildly different SERPs, and ranking timelines depend on competitors who are also working. Forecast to compare opportunities against each other, not to promise a number.
|
||||
|
||||
### What is a good SEO ROI?
|
||||
|
||||
It depends on conversion value and payback window rather than a benchmark. The useful calculation is cost of the content and links against forecast revenue over 12 months, and whether that beats what the same budget would return in paid. SEO usually loses that comparison in month one and wins it by month nine, so the timeline matters as much as the multiple.
|
||||
|
||||
### Which SEO KPIs matter?
|
||||
|
||||
Leads and revenue are the two numbers a business treats as exact. Everything else, including rankings, sessions and impressions, is diagnostic: useful for explaining why the exact numbers moved, weak as a target in its own right.
|
||||
|
||||
### How do you calculate potential traffic from keywords?
|
||||
|
||||
Combined cluster volume, times the CTR for your expected position, gives estimated sessions. Multiply by conversion rate and conversion value for revenue. Run it three times at three positions so you finish with a range rather than a single figure nobody should trust.
|
||||
85
web/content/marketing/library/positioning-to-demand.mdx
Normal file
85
web/content/marketing/library/positioning-to-demand.mdx
Normal file
@ -0,0 +1,85 @@
|
||||
---
|
||||
title: "Check that somebody searches for what you call it"
|
||||
description: "Positioning that no one searches for is a marketing problem disguised as an SEO problem. Validate the words before you build a company around them."
|
||||
---
|
||||
|
||||
## Does your positioning have any search demand behind it?
|
||||
|
||||
Most keyword research starts after the naming is done. The category is chosen, the tagline is written, the site is built, and only then does anyone check whether the words on the homepage match anything a person types. By that point the words are expensive to change.
|
||||
|
||||
The check itself takes minutes. Take the term you use to describe what you sell, and look up whether it has search volume, what the results for it show, and what people search instead. Three outcomes are possible. The term has demand and matching results, so you compete for it. The term has demand but the results answer a different question, so your positioning collides with an intent you cannot win. Or the term has no demand at all, which is the case worth planning for, because it is the most common and the least discussed.
|
||||
|
||||
## The name with no market behind it
|
||||
|
||||
George Little now runs a consultancy with a clear offering. An earlier version of the same company did not survive, and the reason was linguistic:
|
||||
|
||||
> I had another version of this company that did not succeed a couple of years ago that was basically trying to push fractional creative director. No market for it, no search around it. Speaking of SEO, that's really a good place to start. Is anyone even Googling this? And they weren't. So I realized that what they were Googling was agencies and freelancers and this kind of consultant in between.
|
||||
|
||||
Running his term through the tool now shows what he found the hard way:
|
||||
|
||||

|
||||
|
||||
Nine keywords in the entire universe. The term itself does 140 searches a month, and almost everything around it is informational or navigational: people looking up what fractional working means, or searching for jobs. The one term with real volume is a company name. There is no row here belonging to somebody trying to hire this role, which is the demand a business built on the phrase would have needed.
|
||||
|
||||
"Is anyone even Googling this" is the whole strategy in five words. Notice what the check gave him beyond a yes or no. It also returned the vocabulary the market does use: agencies, freelancers, and the space between them. A term with no volume is not only a warning. It is a pointer to the words that carry the demand instead.
|
||||
|
||||
This is the failure mode behind a lot of category creation. Inventing a name for what you do feels like differentiation, and it reads as differentiation on a pitch deck. In a search box it reads as nothing at all. You can still use the invented term inside the relationship, in sales calls and in messaging where you have someone's attention. What you cannot do is expect it to be the door people walk through.
|
||||
|
||||
## The opposite case: language that already has a wave behind it
|
||||
|
||||
The inverse is more useful, and rarer, because it involves matching demand you did not have to create. Holly Homer learned SEO by accident this way. She wrote a review of a product from a late-night infomercial, and by her own account she had no idea what she was doing:
|
||||
|
||||
> I parroted the keywords from the infomercial not knowing what I was doing and just would give my two cents.
|
||||
|
||||
Her blog ran three to five thousand page views a week. The post took it to a hundred thousand.
|
||||
|
||||
> It was because I hit the first page. Actually, it was the first result for pajama jean review at the time. And what I found out later was that Pajama Jeans was doing this massive radio campaign. And so people were going to Google and looking for pajama jean information, and they were landing on my blog.
|
||||
|
||||
She won by using the exact language a national ad campaign was pushing into people's heads at the moment it was pushing it. She did not invent a term or educate a market. She matched vocabulary that already existed and rode demand somebody else paid to create.
|
||||
|
||||
Both stories point the same direction. The words that work are the ones already in circulation, and finding them is [seeding from conversation](/library/keyword-research/seed-from-conversation) applied to your own positioning rather than your content calendar.
|
||||
|
||||
## How to validate a name before you commit
|
||||
|
||||
Run this before the logo, and certainly before the domain purchase:
|
||||
|
||||
1. Look up your candidate term and its obvious variants for search volume. Zero volume is a finding, not a dead end.
|
||||
2. Search the term and read the top ten. If the results answer a question you do not answer, the term is claimed by a different intent.
|
||||
3. Look up the terms your customers used in the last ten sales conversations. That list is the demand-side vocabulary.
|
||||
4. Compare. Where your language and their language differ, theirs wins for anything a stranger has to find.
|
||||
|
||||
Step four is where people flinch, because the customer's phrasing is usually less distinctive than the one the founders like. Keep the distinctive term for the pitch and the relationship. Use their words on the pages that have to be found by somebody who has never met you.
|
||||
|
||||
## Do it with OpenSEO
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP, research "[my category term]" and these
|
||||
variants: [list]. Report search volume, difficulty, and intent for each.
|
||||
|
||||
For any term returning little or no volume, tell me what related terms
|
||||
DO carry volume, and what the top 10 results for those terms are
|
||||
selling. I want the vocabulary the market uses instead of mine.
|
||||
|
||||
Then compare that list against how my customers describe the problem
|
||||
in their own words: [paste from sales calls or support tickets].
|
||||
Show me where my language and their language diverge, and which of
|
||||
their phrasings I should own on the pages a stranger has to find.
|
||||
```
|
||||
|
||||
## What to do first
|
||||
|
||||
Take the phrase on your homepage that describes what you sell, and look up its volume. If the number is zero, the sentence is doing no acquisition work, and the words that would are sitting in your last ten sales calls. That is a cheap discovery to make now and an expensive one to make in a year.
|
||||
|
||||
## Positioning and search demand FAQ
|
||||
|
||||
### Should I invent a name for my category?
|
||||
|
||||
Only with a plan for the demand gap. An invented term has no search behind it on day one and may never earn any, so anything a stranger needs to find has to be findable through the vocabulary that already exists. Keep the invented term for the pitch, where you have someone's attention.
|
||||
|
||||
### What if my keyword has no search volume?
|
||||
|
||||
Treat it as a signal about the market rather than a limitation of the tool. Zero volume for a category term usually means people describe the problem differently, and the related terms that do have volume will show you how. Low volume is different from zero, and can be worth owning when the intent is strong.
|
||||
|
||||
### How do I find the words my customers use?
|
||||
|
||||
Sales calls, support tickets, and recorded interviews, which is the same source that produces good seed keywords. People describe problems in language that no keyword database originates, because the database only knows what has already been typed enough times to register.
|
||||
@ -19,12 +19,12 @@ Search intent is the goal a searcher has when they type a query: to learn, to co
|
||||
The 4-type taxonomy is fine for textbooks. For planning a content calendar, temperature is faster:
|
||||
|
||||
- **Hot: ready now.** Transactional and high-commercial queries. Buyer intent keywords like "X vs Y", "X pricing", "best X for [niche]". Build these pages first: smallest traffic, largest revenue.
|
||||
- **Warm: comparing.** Commercial-investigation queries. They know the problem, they're shortlisting solutions. Comparison pages, use-case pages, honest alternative pages.
|
||||
- **Warm: comparing.** Commercial-investigation queries. They know the problem, they're shortlisting solutions. Comparison pages, use-case pages, and alternative pages that state the tradeoffs.
|
||||
- **Cold: learning.** Informational queries. Highest volume, longest payback. Their job is trust and retargeting, not conversion. Measure them accordingly.
|
||||
|
||||

|
||||
|
||||
Run this play with the [OpenSEO MCP](/docs/mcp):
|
||||
Run this workflow with the [OpenSEO MCP](/docs/mcp):
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP: research keywords for "[your topic]" and group
|
||||
|
||||
@ -21,7 +21,7 @@ Tools recycle each other's databases. Your sales calls, support tickets, and pod
|
||||
|
||||

|
||||
|
||||
Run this play with the [OpenSEO MCP](/docs/mcp):
|
||||
Run this workflow with the [OpenSEO MCP](/docs/mcp):
|
||||
|
||||
```text
|
||||
Using the OpenSEO MCP: here are 8 phrases my customers actually said:
|
||||
@ -41,4 +41,4 @@ Conversations for seeds (this page), Google autocomplete + People Also Ask for e
|
||||
|
||||
### How many seed keywords do I need?
|
||||
|
||||
5–15 strong seeds per topic. Past that you're expanding, not seeding. Feed them into [the long-tail mining play](/library/keyword-research/long-tail-question-mining) next.
|
||||
5–15 strong seeds per topic. Past that you're expanding, not seeding. Feed them into [the long-tail mining strategy](/library/keyword-research/long-tail-question-mining) next. The same customer vocabulary is worth pointing at your own positioning: see [whether anyone searches for what you call yourself](/library/keyword-research/positioning-to-demand).
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 40 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 74 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 70 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
@ -41,7 +41,11 @@ import { Route as MarketingFeaturesAiBrandVisibilityRouteImport } from './routes
|
||||
import { Route as MarketingLibraryKeywordResearchIndexRouteImport } from './routes/_marketing/library/keyword-research/index'
|
||||
import { Route as MarketingLibraryKeywordResearchSeedFromConversationRouteImport } from './routes/_marketing/library/keyword-research/seed-from-conversation'
|
||||
import { Route as MarketingLibraryKeywordResearchSearchIntentMappingRouteImport } from './routes/_marketing/library/keyword-research/search-intent-mapping'
|
||||
import { Route as MarketingLibraryKeywordResearchPositioningToDemandRouteImport } from './routes/_marketing/library/keyword-research/positioning-to-demand'
|
||||
import { Route as MarketingLibraryKeywordResearchOpportunitySizingForecastingRouteImport } from './routes/_marketing/library/keyword-research/opportunity-sizing-forecasting'
|
||||
import { Route as MarketingLibraryKeywordResearchLongTailQuestionMiningRouteImport } from './routes/_marketing/library/keyword-research/long-tail-question-mining'
|
||||
import { Route as MarketingLibraryKeywordResearchIntentBeyondGoogleRouteImport } from './routes/_marketing/library/keyword-research/intent-beyond-google'
|
||||
import { Route as MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRouteImport } from './routes/_marketing/library/keyword-research/gsc-programmatic-discovery'
|
||||
import { Route as MarketingLibraryKeywordResearchClusterTopicalHubsRouteImport } from './routes/_marketing/library/keyword-research/cluster-topical-hubs'
|
||||
|
||||
const TermsAndConditionsRoute = TermsAndConditionsRouteImport.update({
|
||||
@ -217,12 +221,38 @@ const MarketingLibraryKeywordResearchSearchIntentMappingRoute =
|
||||
path: '/library/keyword-research/search-intent-mapping',
|
||||
getParentRoute: () => MarketingRoute,
|
||||
} as any)
|
||||
const MarketingLibraryKeywordResearchPositioningToDemandRoute =
|
||||
MarketingLibraryKeywordResearchPositioningToDemandRouteImport.update({
|
||||
id: '/library/keyword-research/positioning-to-demand',
|
||||
path: '/library/keyword-research/positioning-to-demand',
|
||||
getParentRoute: () => MarketingRoute,
|
||||
} as any)
|
||||
const MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute =
|
||||
MarketingLibraryKeywordResearchOpportunitySizingForecastingRouteImport.update(
|
||||
{
|
||||
id: '/library/keyword-research/opportunity-sizing-forecasting',
|
||||
path: '/library/keyword-research/opportunity-sizing-forecasting',
|
||||
getParentRoute: () => MarketingRoute,
|
||||
} as any,
|
||||
)
|
||||
const MarketingLibraryKeywordResearchLongTailQuestionMiningRoute =
|
||||
MarketingLibraryKeywordResearchLongTailQuestionMiningRouteImport.update({
|
||||
id: '/library/keyword-research/long-tail-question-mining',
|
||||
path: '/library/keyword-research/long-tail-question-mining',
|
||||
getParentRoute: () => MarketingRoute,
|
||||
} as any)
|
||||
const MarketingLibraryKeywordResearchIntentBeyondGoogleRoute =
|
||||
MarketingLibraryKeywordResearchIntentBeyondGoogleRouteImport.update({
|
||||
id: '/library/keyword-research/intent-beyond-google',
|
||||
path: '/library/keyword-research/intent-beyond-google',
|
||||
getParentRoute: () => MarketingRoute,
|
||||
} as any)
|
||||
const MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute =
|
||||
MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRouteImport.update({
|
||||
id: '/library/keyword-research/gsc-programmatic-discovery',
|
||||
path: '/library/keyword-research/gsc-programmatic-discovery',
|
||||
getParentRoute: () => MarketingRoute,
|
||||
} as any)
|
||||
const MarketingLibraryKeywordResearchClusterTopicalHubsRoute =
|
||||
MarketingLibraryKeywordResearchClusterTopicalHubsRouteImport.update({
|
||||
id: '/library/keyword-research/cluster-topical-hubs',
|
||||
@ -260,7 +290,11 @@ export interface FileRoutesByFullPath {
|
||||
'/features/site-audit': typeof MarketingFeaturesSiteAuditRoute
|
||||
'/features/': typeof MarketingFeaturesIndexRoute
|
||||
'/library/keyword-research/cluster-topical-hubs': typeof MarketingLibraryKeywordResearchClusterTopicalHubsRoute
|
||||
'/library/keyword-research/gsc-programmatic-discovery': typeof MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute
|
||||
'/library/keyword-research/intent-beyond-google': typeof MarketingLibraryKeywordResearchIntentBeyondGoogleRoute
|
||||
'/library/keyword-research/long-tail-question-mining': typeof MarketingLibraryKeywordResearchLongTailQuestionMiningRoute
|
||||
'/library/keyword-research/opportunity-sizing-forecasting': typeof MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute
|
||||
'/library/keyword-research/positioning-to-demand': typeof MarketingLibraryKeywordResearchPositioningToDemandRoute
|
||||
'/library/keyword-research/search-intent-mapping': typeof MarketingLibraryKeywordResearchSearchIntentMappingRoute
|
||||
'/library/keyword-research/seed-from-conversation': typeof MarketingLibraryKeywordResearchSeedFromConversationRoute
|
||||
'/library/keyword-research/': typeof MarketingLibraryKeywordResearchIndexRoute
|
||||
@ -295,7 +329,11 @@ export interface FileRoutesByTo {
|
||||
'/features/site-audit': typeof MarketingFeaturesSiteAuditRoute
|
||||
'/features': typeof MarketingFeaturesIndexRoute
|
||||
'/library/keyword-research/cluster-topical-hubs': typeof MarketingLibraryKeywordResearchClusterTopicalHubsRoute
|
||||
'/library/keyword-research/gsc-programmatic-discovery': typeof MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute
|
||||
'/library/keyword-research/intent-beyond-google': typeof MarketingLibraryKeywordResearchIntentBeyondGoogleRoute
|
||||
'/library/keyword-research/long-tail-question-mining': typeof MarketingLibraryKeywordResearchLongTailQuestionMiningRoute
|
||||
'/library/keyword-research/opportunity-sizing-forecasting': typeof MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute
|
||||
'/library/keyword-research/positioning-to-demand': typeof MarketingLibraryKeywordResearchPositioningToDemandRoute
|
||||
'/library/keyword-research/search-intent-mapping': typeof MarketingLibraryKeywordResearchSearchIntentMappingRoute
|
||||
'/library/keyword-research/seed-from-conversation': typeof MarketingLibraryKeywordResearchSeedFromConversationRoute
|
||||
'/library/keyword-research': typeof MarketingLibraryKeywordResearchIndexRoute
|
||||
@ -332,7 +370,11 @@ export interface FileRoutesById {
|
||||
'/_marketing/features/site-audit': typeof MarketingFeaturesSiteAuditRoute
|
||||
'/_marketing/features/': typeof MarketingFeaturesIndexRoute
|
||||
'/_marketing/library/keyword-research/cluster-topical-hubs': typeof MarketingLibraryKeywordResearchClusterTopicalHubsRoute
|
||||
'/_marketing/library/keyword-research/gsc-programmatic-discovery': typeof MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute
|
||||
'/_marketing/library/keyword-research/intent-beyond-google': typeof MarketingLibraryKeywordResearchIntentBeyondGoogleRoute
|
||||
'/_marketing/library/keyword-research/long-tail-question-mining': typeof MarketingLibraryKeywordResearchLongTailQuestionMiningRoute
|
||||
'/_marketing/library/keyword-research/opportunity-sizing-forecasting': typeof MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute
|
||||
'/_marketing/library/keyword-research/positioning-to-demand': typeof MarketingLibraryKeywordResearchPositioningToDemandRoute
|
||||
'/_marketing/library/keyword-research/search-intent-mapping': typeof MarketingLibraryKeywordResearchSearchIntentMappingRoute
|
||||
'/_marketing/library/keyword-research/seed-from-conversation': typeof MarketingLibraryKeywordResearchSeedFromConversationRoute
|
||||
'/_marketing/library/keyword-research/': typeof MarketingLibraryKeywordResearchIndexRoute
|
||||
@ -369,7 +411,11 @@ export interface FileRouteTypes {
|
||||
| '/features/site-audit'
|
||||
| '/features/'
|
||||
| '/library/keyword-research/cluster-topical-hubs'
|
||||
| '/library/keyword-research/gsc-programmatic-discovery'
|
||||
| '/library/keyword-research/intent-beyond-google'
|
||||
| '/library/keyword-research/long-tail-question-mining'
|
||||
| '/library/keyword-research/opportunity-sizing-forecasting'
|
||||
| '/library/keyword-research/positioning-to-demand'
|
||||
| '/library/keyword-research/search-intent-mapping'
|
||||
| '/library/keyword-research/seed-from-conversation'
|
||||
| '/library/keyword-research/'
|
||||
@ -404,7 +450,11 @@ export interface FileRouteTypes {
|
||||
| '/features/site-audit'
|
||||
| '/features'
|
||||
| '/library/keyword-research/cluster-topical-hubs'
|
||||
| '/library/keyword-research/gsc-programmatic-discovery'
|
||||
| '/library/keyword-research/intent-beyond-google'
|
||||
| '/library/keyword-research/long-tail-question-mining'
|
||||
| '/library/keyword-research/opportunity-sizing-forecasting'
|
||||
| '/library/keyword-research/positioning-to-demand'
|
||||
| '/library/keyword-research/search-intent-mapping'
|
||||
| '/library/keyword-research/seed-from-conversation'
|
||||
| '/library/keyword-research'
|
||||
@ -440,7 +490,11 @@ export interface FileRouteTypes {
|
||||
| '/_marketing/features/site-audit'
|
||||
| '/_marketing/features/'
|
||||
| '/_marketing/library/keyword-research/cluster-topical-hubs'
|
||||
| '/_marketing/library/keyword-research/gsc-programmatic-discovery'
|
||||
| '/_marketing/library/keyword-research/intent-beyond-google'
|
||||
| '/_marketing/library/keyword-research/long-tail-question-mining'
|
||||
| '/_marketing/library/keyword-research/opportunity-sizing-forecasting'
|
||||
| '/_marketing/library/keyword-research/positioning-to-demand'
|
||||
| '/_marketing/library/keyword-research/search-intent-mapping'
|
||||
| '/_marketing/library/keyword-research/seed-from-conversation'
|
||||
| '/_marketing/library/keyword-research/'
|
||||
@ -688,6 +742,20 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof MarketingLibraryKeywordResearchSearchIntentMappingRouteImport
|
||||
parentRoute: typeof MarketingRoute
|
||||
}
|
||||
'/_marketing/library/keyword-research/positioning-to-demand': {
|
||||
id: '/_marketing/library/keyword-research/positioning-to-demand'
|
||||
path: '/library/keyword-research/positioning-to-demand'
|
||||
fullPath: '/library/keyword-research/positioning-to-demand'
|
||||
preLoaderRoute: typeof MarketingLibraryKeywordResearchPositioningToDemandRouteImport
|
||||
parentRoute: typeof MarketingRoute
|
||||
}
|
||||
'/_marketing/library/keyword-research/opportunity-sizing-forecasting': {
|
||||
id: '/_marketing/library/keyword-research/opportunity-sizing-forecasting'
|
||||
path: '/library/keyword-research/opportunity-sizing-forecasting'
|
||||
fullPath: '/library/keyword-research/opportunity-sizing-forecasting'
|
||||
preLoaderRoute: typeof MarketingLibraryKeywordResearchOpportunitySizingForecastingRouteImport
|
||||
parentRoute: typeof MarketingRoute
|
||||
}
|
||||
'/_marketing/library/keyword-research/long-tail-question-mining': {
|
||||
id: '/_marketing/library/keyword-research/long-tail-question-mining'
|
||||
path: '/library/keyword-research/long-tail-question-mining'
|
||||
@ -695,6 +763,20 @@ declare module '@tanstack/react-router' {
|
||||
preLoaderRoute: typeof MarketingLibraryKeywordResearchLongTailQuestionMiningRouteImport
|
||||
parentRoute: typeof MarketingRoute
|
||||
}
|
||||
'/_marketing/library/keyword-research/intent-beyond-google': {
|
||||
id: '/_marketing/library/keyword-research/intent-beyond-google'
|
||||
path: '/library/keyword-research/intent-beyond-google'
|
||||
fullPath: '/library/keyword-research/intent-beyond-google'
|
||||
preLoaderRoute: typeof MarketingLibraryKeywordResearchIntentBeyondGoogleRouteImport
|
||||
parentRoute: typeof MarketingRoute
|
||||
}
|
||||
'/_marketing/library/keyword-research/gsc-programmatic-discovery': {
|
||||
id: '/_marketing/library/keyword-research/gsc-programmatic-discovery'
|
||||
path: '/library/keyword-research/gsc-programmatic-discovery'
|
||||
fullPath: '/library/keyword-research/gsc-programmatic-discovery'
|
||||
preLoaderRoute: typeof MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRouteImport
|
||||
parentRoute: typeof MarketingRoute
|
||||
}
|
||||
'/_marketing/library/keyword-research/cluster-topical-hubs': {
|
||||
id: '/_marketing/library/keyword-research/cluster-topical-hubs'
|
||||
path: '/library/keyword-research/cluster-topical-hubs'
|
||||
@ -723,7 +805,11 @@ interface MarketingRouteChildren {
|
||||
MarketingFeaturesSiteAuditRoute: typeof MarketingFeaturesSiteAuditRoute
|
||||
MarketingFeaturesIndexRoute: typeof MarketingFeaturesIndexRoute
|
||||
MarketingLibraryKeywordResearchClusterTopicalHubsRoute: typeof MarketingLibraryKeywordResearchClusterTopicalHubsRoute
|
||||
MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute: typeof MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute
|
||||
MarketingLibraryKeywordResearchIntentBeyondGoogleRoute: typeof MarketingLibraryKeywordResearchIntentBeyondGoogleRoute
|
||||
MarketingLibraryKeywordResearchLongTailQuestionMiningRoute: typeof MarketingLibraryKeywordResearchLongTailQuestionMiningRoute
|
||||
MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute: typeof MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute
|
||||
MarketingLibraryKeywordResearchPositioningToDemandRoute: typeof MarketingLibraryKeywordResearchPositioningToDemandRoute
|
||||
MarketingLibraryKeywordResearchSearchIntentMappingRoute: typeof MarketingLibraryKeywordResearchSearchIntentMappingRoute
|
||||
MarketingLibraryKeywordResearchSeedFromConversationRoute: typeof MarketingLibraryKeywordResearchSeedFromConversationRoute
|
||||
MarketingLibraryKeywordResearchIndexRoute: typeof MarketingLibraryKeywordResearchIndexRoute
|
||||
@ -749,8 +835,16 @@ const MarketingRouteChildren: MarketingRouteChildren = {
|
||||
MarketingFeaturesIndexRoute: MarketingFeaturesIndexRoute,
|
||||
MarketingLibraryKeywordResearchClusterTopicalHubsRoute:
|
||||
MarketingLibraryKeywordResearchClusterTopicalHubsRoute,
|
||||
MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute:
|
||||
MarketingLibraryKeywordResearchGscProgrammaticDiscoveryRoute,
|
||||
MarketingLibraryKeywordResearchIntentBeyondGoogleRoute:
|
||||
MarketingLibraryKeywordResearchIntentBeyondGoogleRoute,
|
||||
MarketingLibraryKeywordResearchLongTailQuestionMiningRoute:
|
||||
MarketingLibraryKeywordResearchLongTailQuestionMiningRoute,
|
||||
MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute:
|
||||
MarketingLibraryKeywordResearchOpportunitySizingForecastingRoute,
|
||||
MarketingLibraryKeywordResearchPositioningToDemandRoute:
|
||||
MarketingLibraryKeywordResearchPositioningToDemandRoute,
|
||||
MarketingLibraryKeywordResearchSearchIntentMappingRoute:
|
||||
MarketingLibraryKeywordResearchSearchIntentMappingRoute,
|
||||
MarketingLibraryKeywordResearchSeedFromConversationRoute:
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
||||
import Content, {
|
||||
frontmatter,
|
||||
} from "../../../../../content/marketing/library/gsc-programmatic-discovery.mdx";
|
||||
import { LibrarySpokePage } from "@/components/library-page";
|
||||
import { buildPageSeo } from "@/lib/seo";
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_marketing/library/keyword-research/gsc-programmatic-discovery",
|
||||
)({
|
||||
head: () =>
|
||||
buildPageSeo({
|
||||
title: "Search Console Keyword Research: Striking-Distance Queries",
|
||||
description: frontmatter.description,
|
||||
path: "/library/keyword-research/gsc-programmatic-discovery",
|
||||
titleSuffix: "OpenSEO Library",
|
||||
ogType: "article",
|
||||
}),
|
||||
component: () => (
|
||||
<LibrarySpokePage
|
||||
title={frontmatter.title}
|
||||
description={frontmatter.description}
|
||||
crumb="Programmatic discovery with Search Console"
|
||||
>
|
||||
<Content components={{ ...defaultMdxComponents }} />
|
||||
</LibrarySpokePage>
|
||||
),
|
||||
});
|
||||
@ -3,7 +3,7 @@ import { buildPageSeo } from "@/lib/seo";
|
||||
|
||||
const PATH = "/library/keyword-research";
|
||||
|
||||
const plays = [
|
||||
const strategies = [
|
||||
{
|
||||
title: "Seed from conversation, not a volume report",
|
||||
description:
|
||||
@ -32,21 +32,25 @@ const plays = [
|
||||
title: "Programmatic discovery with Search Console",
|
||||
description:
|
||||
"Query-mine your own GSC by MCP: striking-distance keywords, zero-click pages, dark queries.",
|
||||
href: "/library/keyword-research/gsc-programmatic-discovery",
|
||||
},
|
||||
{
|
||||
title: "Opportunity sizing & forecasting",
|
||||
description:
|
||||
"Size a cluster before you invest: difficulty, traffic ceiling, and honest payback windows.",
|
||||
"Size a cluster before you invest: difficulty, traffic ceiling, and modeled payback windows.",
|
||||
href: "/library/keyword-research/opportunity-sizing-forecasting",
|
||||
},
|
||||
{
|
||||
title: "Intent beyond Google (Pinterest, AI, LinkedIn)",
|
||||
description:
|
||||
"Where queries happen when they don't happen in a search box, AI assistants included.",
|
||||
href: "/library/keyword-research/intent-beyond-google",
|
||||
},
|
||||
{
|
||||
title: "Map positioning to real demand",
|
||||
description:
|
||||
"Competitor keyword gaps as a positioning instrument, not a copying exercise.",
|
||||
"Check whether your category language matches what customers actually search.",
|
||||
href: "/library/keyword-research/positioning-to-demand",
|
||||
},
|
||||
];
|
||||
|
||||
@ -93,7 +97,7 @@ export const Route = createFileRoute("/_marketing/library/keyword-research/")({
|
||||
buildPageSeo({
|
||||
title: "How to Do Keyword Research: The Strategy Library",
|
||||
description:
|
||||
"Eight practitioner plays that treat keyword research as demand discovery, sourced from real interviews with working SEOs, executable inside OpenSEO.",
|
||||
"Eight demand-discovery strategies drawn from interviews with working SEOs, each with a workflow you can run in OpenSEO.",
|
||||
path: PATH,
|
||||
titleSuffix: "OpenSEO",
|
||||
}),
|
||||
@ -111,9 +115,8 @@ function KeywordResearchLibraryPage() {
|
||||
The Keyword Research Strategy Library
|
||||
</h1>
|
||||
<p className="mt-5 text-lg leading-8 text-[var(--color-brand-muted)]">
|
||||
Eight practitioner plays that treat keyword research as demand
|
||||
discovery, sourced from real interviews with working SEOs, executable
|
||||
inside OpenSEO.
|
||||
Eight demand-discovery strategies drawn from interviews with working
|
||||
SEOs, each with a workflow you can run in OpenSEO.
|
||||
</p>
|
||||
</header>
|
||||
|
||||
@ -123,13 +126,14 @@ function KeywordResearchLibraryPage() {
|
||||
</h2>
|
||||
<p className="mt-2 max-w-2xl text-sm leading-6 text-[var(--color-brand-muted)]">
|
||||
Most guides teach you to export a volume report and sort descending.
|
||||
These plays start earlier, where demand originates: customer language,
|
||||
question mining, your own Search Console. They end with pages mapped
|
||||
to intent, not keywords stuffed into paragraphs. Each play is a full
|
||||
walkthrough with the copy-paste MCP prompt that runs it.
|
||||
These strategies start earlier, where demand originates: customer
|
||||
language, question mining, your own Search Console. They end with
|
||||
pages mapped to intent, not keywords stuffed into paragraphs. Each
|
||||
strategy includes a walkthrough and a copy-paste MCP prompt for the
|
||||
workflow.
|
||||
</p>
|
||||
<div className="mt-6 grid gap-4 md:grid-cols-2">
|
||||
{plays.map((play, index) => {
|
||||
{strategies.map((strategy, index) => {
|
||||
const number = String(index + 1).padStart(2, "0");
|
||||
const body = (
|
||||
<>
|
||||
@ -137,15 +141,15 @@ function KeywordResearchLibraryPage() {
|
||||
<span className="font-mono text-sm tabular-nums text-[var(--color-brand-accent)]">
|
||||
{number}
|
||||
</span>
|
||||
{play.href ? null : (
|
||||
{strategy.href ? null : (
|
||||
<span className="rounded-full border border-[var(--color-border-subtle)] px-2 py-0.5 font-mono text-[10px] uppercase tracking-wider text-[var(--color-brand-muted)]">
|
||||
Next up
|
||||
</span>
|
||||
)}
|
||||
</div>
|
||||
<h3 className="mt-3 text-base font-semibold text-neutral-950">
|
||||
{play.title}
|
||||
{play.href ? (
|
||||
{strategy.title}
|
||||
{strategy.href ? (
|
||||
<span
|
||||
aria-hidden="true"
|
||||
className="ml-1 text-[var(--color-brand-accent)]"
|
||||
@ -155,21 +159,21 @@ function KeywordResearchLibraryPage() {
|
||||
) : null}
|
||||
</h3>
|
||||
<p className="mt-2 text-sm leading-6 text-[var(--color-brand-muted)]">
|
||||
{play.description}
|
||||
{strategy.description}
|
||||
</p>
|
||||
</>
|
||||
);
|
||||
return play.href ? (
|
||||
return strategy.href ? (
|
||||
<a
|
||||
key={play.title}
|
||||
href={play.href}
|
||||
key={strategy.title}
|
||||
href={strategy.href}
|
||||
className="rounded-lg border border-[var(--color-border-subtle)] bg-white p-5 transition-colors hover:border-neutral-900"
|
||||
>
|
||||
{body}
|
||||
</a>
|
||||
) : (
|
||||
<div
|
||||
key={play.title}
|
||||
key={strategy.title}
|
||||
className="rounded-lg border border-[var(--color-border-subtle)] bg-white p-5"
|
||||
>
|
||||
{body}
|
||||
@ -179,7 +183,7 @@ function KeywordResearchLibraryPage() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className="mt-12 rounded-xl border border-[var(--color-border-subtle)] bg-white p-6 md:p-8">
|
||||
<section className="mt-12">
|
||||
<h2 className="text-2xl font-semibold tracking-tight text-neutral-950">
|
||||
What Google Keyword Planner hides (and what to use instead)
|
||||
</h2>
|
||||
@ -190,20 +194,21 @@ function KeywordResearchLibraryPage() {
|
||||
for content strategy.
|
||||
</p>
|
||||
<p className="mt-3 max-w-3xl text-sm leading-6 text-neutral-700">
|
||||
The plays in this library replace it with three honest sources: your
|
||||
customers' language (play 01), Google's own question surfaces (play
|
||||
02), and your Search Console reality (play 05). Volume data still
|
||||
matters, but it's the <em>last</em> filter, not the first.
|
||||
The strategies in this library replace it with three sources you can
|
||||
inspect: your customers' language (strategy 01), Google's own question
|
||||
surfaces (strategy 02), and your Search Console reality (strategy 05).
|
||||
Volume data still matters, but it's the <em>last</em> filter, not the
|
||||
first.
|
||||
</p>
|
||||
</section>
|
||||
|
||||
<section className="mt-12">
|
||||
<h2 className="text-2xl font-semibold tracking-tight text-neutral-950">
|
||||
Free keyword research tools for every play
|
||||
Free keyword research tools for every strategy
|
||||
</h2>
|
||||
<p className="mt-2 max-w-2xl text-sm leading-6 text-[var(--color-brand-muted)]">
|
||||
Google's free surfaces (autocomplete, People Also Ask) plus your own
|
||||
Search Console do the discovery. Every play then runs in{" "}
|
||||
Search Console do the discovery. You can run each workflow in{" "}
|
||||
<a
|
||||
href="/features/keyword-research"
|
||||
className="font-medium text-neutral-950 underline decoration-[var(--color-brand-accent)] underline-offset-4"
|
||||
@ -248,8 +253,8 @@ function KeywordResearchLibraryPage() {
|
||||
The Keyword Research Playbook
|
||||
</h2>
|
||||
<p className="mt-2 max-w-xl text-sm leading-6 text-[var(--color-brand-muted)]">
|
||||
The plays as a working PDF: checklists, the MCP prompts, and the
|
||||
keyword-map template. Ungated.
|
||||
The strategies as a working PDF: checklists, the MCP prompts, and
|
||||
the keyword-map template. Ungated.
|
||||
</p>
|
||||
</div>
|
||||
<a
|
||||
|
||||
@ -0,0 +1,29 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
||||
import Content, {
|
||||
frontmatter,
|
||||
} from "../../../../../content/marketing/library/intent-beyond-google.mdx";
|
||||
import { LibrarySpokePage } from "@/components/library-page";
|
||||
import { buildPageSeo } from "@/lib/seo";
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_marketing/library/keyword-research/intent-beyond-google",
|
||||
)({
|
||||
head: () =>
|
||||
buildPageSeo({
|
||||
title: "Keyword Research Beyond Google: Pinterest, LinkedIn and AI",
|
||||
description: frontmatter.description,
|
||||
path: "/library/keyword-research/intent-beyond-google",
|
||||
titleSuffix: "OpenSEO Library",
|
||||
ogType: "article",
|
||||
}),
|
||||
component: () => (
|
||||
<LibrarySpokePage
|
||||
title={frontmatter.title}
|
||||
description={frontmatter.description}
|
||||
crumb="Intent beyond Google"
|
||||
>
|
||||
<Content components={{ ...defaultMdxComponents }} />
|
||||
</LibrarySpokePage>
|
||||
),
|
||||
});
|
||||
@ -0,0 +1,29 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
||||
import Content, {
|
||||
frontmatter,
|
||||
} from "../../../../../content/marketing/library/opportunity-sizing-forecasting.mdx";
|
||||
import { LibrarySpokePage } from "@/components/library-page";
|
||||
import { buildPageSeo } from "@/lib/seo";
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_marketing/library/keyword-research/opportunity-sizing-forecasting",
|
||||
)({
|
||||
head: () =>
|
||||
buildPageSeo({
|
||||
title: "SEO Forecasting: Size a Keyword Opportunity Before You Build",
|
||||
description: frontmatter.description,
|
||||
path: "/library/keyword-research/opportunity-sizing-forecasting",
|
||||
titleSuffix: "OpenSEO Library",
|
||||
ogType: "article",
|
||||
}),
|
||||
component: () => (
|
||||
<LibrarySpokePage
|
||||
title={frontmatter.title}
|
||||
description={frontmatter.description}
|
||||
crumb="Opportunity sizing & forecasting"
|
||||
>
|
||||
<Content components={{ ...defaultMdxComponents }} />
|
||||
</LibrarySpokePage>
|
||||
),
|
||||
});
|
||||
@ -0,0 +1,29 @@
|
||||
import { createFileRoute } from "@tanstack/react-router";
|
||||
import defaultMdxComponents from "fumadocs-ui/mdx";
|
||||
import Content, {
|
||||
frontmatter,
|
||||
} from "../../../../../content/marketing/library/positioning-to-demand.mdx";
|
||||
import { LibrarySpokePage } from "@/components/library-page";
|
||||
import { buildPageSeo } from "@/lib/seo";
|
||||
|
||||
export const Route = createFileRoute(
|
||||
"/_marketing/library/keyword-research/positioning-to-demand",
|
||||
)({
|
||||
head: () =>
|
||||
buildPageSeo({
|
||||
title: "Does Your Positioning Have Search Demand Behind It?",
|
||||
description: frontmatter.description,
|
||||
path: "/library/keyword-research/positioning-to-demand",
|
||||
titleSuffix: "OpenSEO Library",
|
||||
ogType: "article",
|
||||
}),
|
||||
component: () => (
|
||||
<LibrarySpokePage
|
||||
title={frontmatter.title}
|
||||
description={frontmatter.description}
|
||||
crumb="Map positioning to real demand"
|
||||
>
|
||||
<Content components={{ ...defaultMdxComponents }} />
|
||||
</LibrarySpokePage>
|
||||
),
|
||||
});
|
||||
Loading…
x
Reference in New Issue
Block a user