Interview plan template

Use Template
to edit & run interviews

SEO Engineer (Technical SEO & Search Infrastructure) interview questionsEngineering Round — What the Crawler Received round

A 60 min interview plan with a time-boxed script, what each question is for, and the signals to score against. Key skills: Rendering-pipeline diagnosis from raw HTML, crawler-versus-browser reasoning, status-code correctness across user agents, CI assertion design, crawl observability and alerting.

Click "Use template" to edit

Framing and the first command

8 min

I'm [YOUR_NAME], and I own the front-end templates and the build at [COMPANY_NAME] — so this is the implementation half of the conversation you already had with our SEO lead. Three things about the format. You'll have a terminal you can type in and I'll paste responses and files into the chat as we go; I would much rather watch you run something than hear you describe what you would run. The diagnosis you agreed with the SEO lead is on the table, and I'm not going to make you re-argue the whole audit — but if you think any part of it is wrong, this is the round to say so, and I'll ask you directly at one point. And by the end I want two things out of you that I could actually use: a change to a CI assertion, precise enough that I can commit it, and an alert with a number in it. If you get an assertion wrong out loud, that is genuinely fine. I write assertions that cannot fail all the time. That is why this round exists.

Here is one live URL from our library, and here is a terminal. Our SEO lead thinks the content isn't reaching crawlers. My team looks at this page in Chrome every day and sees a complete, correct, well-formatted page. You have three minutes. What do you run, and what number do you want back?

What this question is for, and what to listen for

Purpose

The fastest discriminator in the round, and the one with a trap in it for the interviewer as well as the candidate. Every tool that reports this page as healthy — DevTools Elements, Lighthouse, PageSpeed Insights — executes JavaScript, so reaching for one is a statement that the candidate has never caught this class of defect. The second half of the discriminator is subtler: the obvious measurement does not work either, and saying so out loud is the strongest thing anyone does in the first ten minutes.

Signals to score

  • Runs curl or opens view-source inside the first minute, before opening any graphical tool
  • Says what they expect the number to be before they see it, and expects a raw word count to come back high on a broken page as well as on a healthy one
  • Names what has to come out before a count means anything: script blocks, hidden containers, everything after the last closing footer tag
  • Reaches for a single unambiguous token — a surviving Suspense boundary marker, or a sentence that should be in the body — instead of arithmetic they cannot do in one line of shell
  • Repeats the fetch under a crawler user agent without being told to, using something like curl -sA "GPTBot" or -A "Googlebot"
  • Names the DevTools Elements panel as the post-hydration DOM and says why it cannot answer this particular question
  • Declines Lighthouse or PageSpeed Insights when offered, and gives JavaScript execution as the reason, not a preference
  • Checks status and content-type in the same fetch, with -I or -D -, and does not assume the response is a 200
  • Asks whether the response is being served from a CDN and whether they are looking at a cached copy
  • Greps for a sentence a human would read on the page, not for a tag name or a keyword

Follow-up questions

  • You have curl and nothing else. What is the one command?
  • Suppose the word count comes back at 1,100. Are you finished?
  • I'll give you Lighthouse. The performance score is 96 and SEO is 100. Does that change anything?
  • Is there anywhere in a browser you can get the same answer curl just gave you?
  • The raw response does contain the sentence you grepped for. Now what?

What the crawler received

20 min

Here is the tail of that response, and one line from the middle of the same document. This is real markup from the morning we found it, with the plan text cut down. From the middle of the body, where the plan content should be: <!--$?--><template id="B:1"></template><!--/$--> Everything after the closing footer tag: </footer> <script>self.__next_f.push([1,"...Phase 1 - Discovery... the full plan text, escaped ..."])</script> <div hidden id="S:1"><h1>Sprint plan template</h1><h2>Phase 1 - Discovery</h2><p>... 1,026 words ...</p></div> <script>$RC=function(a,b){...};$RC("B:1","S:1")</script> The numbers that go with it: 1,026 words visible in Chrome. 36 words if you take everything before the last closing footer tag, drop the script blocks and the hidden containers, and strip the markup. That 36 is byte-identical across all 163 URLs. Status 200 to every agent we tried. Tell me what this page is doing. Then tell me who is affected and who isn't, and be specific about which consumers.

What this question is for, and what to listen for

Purpose

Discriminates between candidates who read markup as a mechanism and candidates who pattern-match to a slogan. The consumer split is the real probe, because the two collapsed answers — "Google can't see it" and "Google renders it, so this is fine" — are both wrong, and each one buys you a different wasted quarter.

Signals to score

  • Describes the mechanism in their own words: the shell was emitted as the document, the body arrived afterwards, and a script moves it into position
  • Points at the pending boundary marker or the empty template element as evidence that the document was written before that part was ready
  • Separates two facts explicitly — the content is in the file, and the content is not in the document flow
  • States that Googlebot does render this and therefore ends up holding the correct DOM
  • Distinguishes a sourced render-delay figure from an asserted one: either declines to name a duration, or names one and immediately gives its source and its vintage
  • Names specific non-rendering crawlers — GPTBot, ClaudeBot, PerplexityBot — and says a direct fetch by any of them ends at 36 words with no second pass on that fetch
  • Separates a vendor from its agents, knowing that a crawler that trains, a crawler that builds a search index and a fetcher that runs on demand are different clients, and names at least one crawler that does render, such as Applebot
  • Knows a page can reach an assistant through a third-party index it was never fetched for directly, so "invisible to AI" overstates it
  • Rejects the hidden attribute as a ranking penalty when it is offered to them, and reframes the defect as reachability
  • Treats the 36 words being byte-identical across 163 URLs as a separate finding from the content being late

Follow-up questions

  • Is the hidden attribute the problem here?
  • How long does Google's render queue take?
  • Our head of content read that AI crawlers execute JavaScript now. What is your read on that?
  • The text is in the file. I can grep it and it is right there. Why isn't that good enough?
  • If you had to prove the non-rendering claim to me instead of asserting it, what would you put on the screen?

Take it as settled that Google renders this page and can index it — I don't want that argument again. What I want is the causal claim underneath it. Before Google renders anything, its first pass over this directory sees 163 documents whose in-flow HTML is the same 36 words, and 104 of those URLs came back "Crawled — currently not indexed". How much of that do you put on the rendering defect, how confident are you, and what single piece of evidence would move you? Then the engineering half. That boundary is there because the query behind it is slow and uncached. You want the content in the document, which means you want it cached. What does a cache miss serve, and what invalidates it?

What this question is for, and what to listen for

Purpose

The first half is where candidates over-claim, and where the round is most tempted to reward agreement. The byte-identical first pass is a plausible mechanism, not a proven cause, and the alternative explanation is one this company later adopted — so the question is really whether the candidate can name a hypothesis that contradicts the interviewer. The second half checks whether they can argue caching with the engineer who will implement it and not just file a requirement.

Signals to score

  • Attributes the index count to the rendering defect as a hypothesis, and labels it as one without being pushed to
  • Names at least one non-rendering explanation — thin or near-duplicate content across a templated directory on a low-authority domain — and says which single piece of evidence separates it from the rendering story
  • Names URL Inspection on a sample as the discriminator, and says which result would kill their own hypothesis
  • Names other evidence that would move them: renderer activity in the server logs, indexed count on a treated subset against an untreated one
  • Gives a confidence number when asked for one, and it is not 90%
  • Asks what the slow query returns, and whether any of it is per-request or per-user, before agreeing to cache it
  • Asks what the cache-miss path serves, and names the failure precisely: a miss that falls back to the streamed version reintroduces the original defect for exactly the requests most likely to be a crawler's first visit to that URL
  • Ties invalidation to a write path — a publish event, a tag purge on save — and does not stop at naming a time-to-live
  • States the staleness risk out loud and says who would notice it, and how
  • Treats user-agent-conditional serving as a real technique with a real cost when it is offered, neither endorsing it nor reciting that it is banned

Follow-up questions

  • Give me a number for your confidence, and tell me what would move it.
  • The query is slow because it joins per-user personalisation into the page. Does that change the plan?
  • If the cache goes stale, who finds out, and how?
  • Would you take a five-minute time-to-live and move on? Why not?
  • We can server-render this properly in two sprints, or ship a crawler-only version on Friday. Which do you take?

The control

25 min

We had a test for this. It has been in CI since before the bug shipped, it ran on every commit for eleven weeks while every page in the library was serving 36 words, and it was green every single time. Here is the whole assertion: check(file + ' serves "' + question + '"', html.includes(question)); Tell me why it passed.

What this question is for, and what to listen for

Purpose

The pivot of the round. Anybody can agree that a check is needed; this asks why the check that already existed was worthless, and the generalisation the candidate draws predicts every control they will write for us afterwards.

Signals to score

  • Says within the first minute that the assertion tested presence and the content was present, just not in the document
  • Identifies the post-footer hidden container as one thing that satisfies the substring check
  • Identifies the script payload as a second, independent way the same string satisfies it
  • Points out that the assertion would still pass if the body were moved anywhere at all in the file, including into a comment
  • Generalises to the class: the assertion was satisfied by the failure mode, so it could never have fired
  • Names the difference between asserting presence and asserting position, in those terms or equivalent ones
  • Asks whether the check ran against build output or a live URL, and whether that mattered here
  • Says the assertion should have been run against the known-broken artifact before anyone trusted it
  • Treats a green test that cannot fail as the reportable defect, and does not blame whoever wrote the line

Follow-up questions

  • Would a stricter string have saved us — matching three sentences instead of one?
  • If you had inherited this repository, what would have made you suspicious of that line?
  • We also had a check asserting the page returns 200. Why didn't that help?
  • What is the general version of this mistake, outside SEO entirely?
  • Where else in a build would you go looking for assertions that cannot fail?

Then replace it. Dictate the assertions you want in that file — I will type them and you will see them on the screen, so be precise enough that I could commit it. Cover two exhibits, not one. The first is the defect we have been discussing. The second is from the same site this morning, and nothing we run noticed either half of it: /library/sprint-plan-9999, a well-formed ID matching nothing, returns 500 to every user agent and has done since March; and /library/quarterly-roadmap-241 returns 404 to a Googlebot user agent and 200 to Chrome, where the 200 body is our application shell and the visible text on it reads "This page could not be found." When you have the assertions, two more things. Does this run against build output or against a deployed URL? And what alerts a human: which URLs, how often, under which agents, at what threshold, to whom, and what does the first line of the runbook say?

What this question is for, and what to listen for

Purpose

The artifact, and the only point in the loop where the candidate has to produce something mergeable instead of describing something desirable. The specifics — the strip order, the calibration of the floor, the alert threshold — are not improvisable from general knowledge. The second exhibit is what stops this becoming a single-defect check: it is the reason the agent dimension and the deployed-URL half are load-bearing rather than decorative, and a candidate who designs only for the rendering bug will say so themselves once they reach the alert. Budget the full seventeen minutes and protect them; the interviewer is typing, which is slower than it sounds, and this is the section that produces the write-up.

Signals to score

  • Strips script blocks before asserting, and gives the reason: the streaming payload carries the same text verbatim
  • Strips hidden containers, or truncates at the last closing footer tag, so that only in-flow markup is tested
  • Asserts that no pending boundary marker survives anywhere in the response
  • Puts a word floor on in-flow text, states what the number is calibrated against — the empty shell, a per-URL baseline, a fraction of the healthy median — and explains why a floor outlives the string checks around it
  • Asserts exactly one h1, and that it carries a string that differs from page to page
  • Asserts status per user agent and not merely per URL, and grounds it: only 200-status responses are queued for rendering, and a URL whose status depends on who asks cannot be monitored or cached whichever status is correct
  • Answers "both" on build output versus deployed URL, with a distinct job for each and not a preference
  • Asks how the CI fixtures differ from production, and names something a test double could be lying about
  • Specifies the alert with numbers: which URLs, what interval, which agents, what threshold fires, who receives it, one action on receipt
  • Volunteers a condition under which they would delete their own alert

Follow-up questions

  • What is the floor, and where does that number come from?
  • I'll run your check against last month's broken HTML. Does it fail, and which line fails first?
  • Our CI runs against a mock API. What could that mock be lying about?
  • Which of those two status defects would Search Console have shown me, and how long after it started?
  • Our strip is a regular expression, /<div hidden[^>]*>[\s\S]*?<\/div>/g. What breaks it?

What you would leave alone, and what you would need

7 min

Two things to finish. First: name one thing on a page like this that you would deliberately leave out of the server-rendered HTML, and tell me how you would defend that to your own SEO lead. Second, and I would rather you spent the time here: what would you need from me in your first month for anything you have just described to actually ship?

What this question is for, and what to listen for

Purpose

"Server-render everything" is an absence of a position dressed as one, and the first half catches it. The second half is a real question — a candidate who has owned this work has been blocked by access, capacity or ownership, and asks about whichever one burned them.

Signals to score

  • Names something concrete they would leave client-side: interactive state, a view toggle, personalisation, a logged-in panel
  • Justifies it by what the content is worth to a client that never runs JavaScript, and not by performance in general
  • Asks whether any content is being withheld from the HTML deliberately for a reason that is not technical
  • Asks who reviews and merges changes to the templates, and whether they would have commit access or be filing tickets
  • Asks whether this work enters the front-end team's sprint or their own backlog
  • Asks who is paged when their alert fires, and whether that rota includes them
  • Asks what happens the first time their CI check blocks somebody else's release
  • Names one specific access they want on day one — the repository, the CDN configuration, the log store, Search Console — and does not ask about tooling in general

Follow-up questions

  • Would you leave the model answers to these plans in the HTML, or out? Why?
  • Your check blocks a release on a Friday afternoon and the content lead disagrees with it. Who wins?
  • If you had commit access but no engineering capacity, is that enough?
  • Name the one thing you would want in writing before you accepted.

That is what I had. What I write up is the assertion you dictated and whether it would have fired — I still have the broken HTML from March, and I will run your version against it this afternoon and tell you the result either way, including if it passes. Two things you should know before you decide anything about us. The check we have been discussing is real, it is a bit over two hundred lines, and whoever takes this job owns it from day one. And the front-end templates have two reviewers, one of whom is me, which means SEO changes here arrive as pull requests instead of as tickets. [RECRUITER_NAME] will come back to you within [NUMBER] working days.

Use Template
to edit & run interviews
Interview Template
Position
SEO Engineer (Technical SEO & Search Infrastructure)
Round
Engineering Round — What the Crawler Received for 60 min
Key skills
Rendering-pipeline diagnosis from raw HTML, crawler-versus-browser reasoning, status-code correctness across user agents, CI assertion design, crawl observability and alerting

SEO Engineer (Technical SEO & Search Infrastructure) interviews — common questions

Who is this SEO Engineer (Technical SEO & Search Infrastructure) interview plan for?
It is written for the interviewer, not the candidate: the hiring manager, engineer or panel member running the Engineering Round — What the Crawler Received round for a SEO Engineer (Technical SEO & Search Infrastructure) role. It gives you a 60 min script to follow in the conversation — 6 questions with what each one is for and the signals to score against — so you are not writing the round from scratch the night before.
What does the Engineering Round — What the Crawler Received round assess?
This round is focused on: Rendering-pipeline diagnosis from raw HTML, crawler-versus-browser reasoning, status-code correctness across user agents, CI assertion design, crawl observability and alerting. It works through Framing and the first command, What the crawler received, The control and What you would leave alone, and what you would need, scoring against 57 observable signals, with follow-up prompts on all 6 questions for going deeper where an answer is thin.
How is the 60 min split up?
Framing and the first command (8 min), What the crawler received (20 min), The control (25 min), What you would leave alone, and what you would need (7 min). The timings are there so the round stays on schedule and every candidate gets the same shape of interview — which is what makes two candidates comparable afterwards.