Search Console on a new site rarely reports a bug. It reports decisions: which pages Google could reach, which it could read, which it treated as duplicates of each other, which loaded too slowly on a phone. Every one of those was settled by someone on the build, usually without knowing it was an SEO decision, and by the time the report exists the cheap moment to change it has passed.
SEO in web development is the set of build decisions (page inventory, site architecture, URL pattern, rendering, CMS, structured data, performance budget) that determine whether search engines and AI assistants can find, read and index the site. Each is cheap to set while the site is a plan and expensive to unpick once it’s live. A site that gets them wrong spends its first three to six months on cleanup instead of on content.
This is how my team runs every build: custom web development and SEO as one process, with the first batch of content written during development and scored before it goes live. The screenshot further down comes from the tool we built for that, Algorithm.
TL;DR
- The expensive SEO decisions (page inventory, architecture, rendering, the CMS) happen before code. Retrofitting them costs three to six months.
- Each of those decisions has a development half, and nobody tells development. The ownership table assigns the halves.
- Rendering is the decision nobody in the room owns. If the content only exists after JavaScript runs, Google sees it late and crawlers that don’t run scripts don’t see it.
- Core Web Vitals: LCP under 2.5 s, INP under 200 ms, CLS under 0.1, at the 75th percentile of field data.
- Write SEO into the definition of done. The acceptance table near the end has a test and an owner for every row.
How web development and SEO work together: who owns what
SEO usually arrives after launch, to a site whose structure, URL pattern, rendering, load time on a mid-range phone and markup were already settled in code. Each of those decisions has two halves, and the table assigns them. Developers don’t have to become SEO experts, and the reverse is also true; what the two share is the table.
| Decision | SEO owns | Development owns |
|---|---|---|
| Search demand and page inventory | Which pages exist, which intent each one serves, target URL per cluster | Content model and templates that can hold them |
| URL structure | Pattern per page type, slug rules | Routing, trailing slashes, case, parameter handling, redirects |
| Rendering | Which pages must be readable without JavaScript | SSR / SSG / hybrid choice, hydration, framework |
| Metadata and schema | Title and description rules, schema types per template | Editable fields in the CMS, JSON-LD output, validation |
| Performance | Thresholds per template, field-data review at 30 days | Performance budget, image pipeline, script loading, caching |
| Crawl controls | What is indexed, what is blocked, which crawlers are allowed | robots.txt, sitemap generation, canonical logic, status codes |
| Launch | Pre-launch audit, Search Console and tracking set up | Staging block removed, redirects live, monitoring |
Get that table agreed before the first sprint is estimated, because the rows where I see the most damage are rendering and crawl controls, and neither side thinks it owns them. SEO assumes the framework handles rendering; development assumes someone will “do the robots file” later.
Web development and SEO by project phase: what each decision costs to change
Web development and SEO meet in four windows, and the same decision costs more in each one:
| Phase | What gets decided | Cost of changing it later |
|---|---|---|
| Before development | Page inventory, site architecture, URL pattern, rendering strategy, CMS | Highest: structural rewrite or replatform |
| During development | URL implementation, metadata, schema, internal links | Medium: redirects, re-crawl |
| Before launch | The acceptance table, run per template | Low: quick fixes |
| After launch | Everything above, in panic mode | Emergency: months of rankings that don’t arrive |
A site that already ranks pays a second cost, the equity lost while these decisions are made, and the migration work that protects it is in the B2B website redesign guide. This article assumes a clean sheet.
Where development decides SEO: architecture, URLs and the content model
Architecture starts from the keyword map, because the map says which pages have to exist before anyone decides how they nest: the topics, the long-tail variations that reveal intent, the question-shaped queries people now type into an assistant verbatim, clustered and mapped to a target URL each. For the build, one shared sheet is enough, provided the content model has a template for every row in it. A page type the CMS can’t hold is a cluster that never gets a page.
From there the structure is shallow, a handful of primary sections with pages a few clicks from the homepage, every page linked from somewhere a crawler can follow, and one URL pattern per page type, decided before the build and enforced at the server. The slug rules and the routing details are the two halves of the URL row in the ownership table.
Decide the URL pattern before the build, because equity goes missing in redirect maps: a 301 loses nothing by itself (the 301 redirect SEO penalty is a myth), but chains, mismatched targets and internal links left pointing at the old URLs pile up around it, and each one is a page Google reaches late.
The rendering decision: is the content in the HTML?
This is the decision in web development and SEO that lives entirely in code and gets made by default when nobody names it. Ask whether the page’s content is in the HTML the server returns, or appears only after a JavaScript bundle runs in the browser.
Googlebot reads the server HTML first and queues the page for rendering; Google’s documentation says the queue takes “a few seconds, but it can take longer than that”. How much longer for a given site, Google doesn’t publish, and server logs show the crawl, not the render, so I can’t give you a number. Crawlers that don’t run JavaScript never see what the browser builds: in Vercel and MERJ’s December 2024 study, none of the AI crawlers it tracked executed it, with Google’s own as the exception because they share Googlebot’s infrastructure, so a client-rendered page can rank on Google, whose own AI features read the rendered index, and be a blank shell to the assistants with their own crawlers. No framework is bad for SEO; its default rendering mode can be, and that is a question for your developers in week one. The rule I hold: if a page earns organic traffic, its primary content and its internal links belong in the server HTML. Client-side rendering is for dashboards and the states behind a login.
Open the page, view source (Ctrl+U, or Cmd+Option+U on a Mac, which shows what the server sent), and search for a sentence of the main copy; it takes two minutes. If the sentence is there, Google and the AI crawlers can read it. If it only appears in DevTools, you’re depending on a render some crawlers do late and some never do. The mechanics (hydration mismatches, client-side routing without href, prerendering, crawling staging with JavaScript off) are in the technical SEO audit guide.
Performance and markup: where web development decides Core Web Vitals
The LCP failure I find most often is one attribute long: loading="lazy" on the hero image, which tells the browser to defer the one element the metric is measuring. Core Web Vitals are measured on field data from Chrome users at the 75th percentile, read per template, so the listing page, the category page and the homepage fail differently and a site-wide score hides all three. The thresholds, and what breaks each one in a build:
| Metric | “Good” at p75 | What breaks it in the build | Note |
|---|---|---|---|
| LCP, Largest Contentful Paint | under 2.5 s | A slow server (TTFB over 800 ms); a hero image that is lazy-loaded, unsized or too heavy; fonts and styles that block the first paint; the largest element rendered client-side. Fix: the hero in the server HTML with fetchpriority="high", lazy-loading below the fold only | The “tightened to 2.0 s in 2026” claim on SEO blogs is false; Google’s documentation, checked October 2026, still says 2.5 s |
| INP, Interaction to Next Paint | under 200 ms | Main-thread work: a framework re-running the whole page in the browser, a mega-menu, a chat widget, a consent banner and three analytics tags initializing in the same second | Replaced FID in March 2024; a checklist that still says “FID under 100 ms” predates that |
| CLS, Cumulative Layout Shift | under 0.1 | Images, embeds and ad slots without dimensions; fonts that swap late; banners injected above content after load | Reserve the space, every time |
The third-party script inventory (chat, consent, heatmaps, tag managers) is a launch deliverable with an owner, because INP fails on the sum of them and every team says the slow one wasn’t theirs. Markup costs nothing at build time: one H1 that names the topic, headings in outline order whatever size the design draws them, images with dimensions and alt text, links that are links. It’s the same list as the accessibility audit, so it belongs in the component library once. Google indexes the mobile version of each page, so the device check is a mid-range Android over throttled 4G; the rest of it is in our mobile SEO checklist.
Crawl controls, structured data and the CMS
A staging noindex shipped to production is the launch-day bug I get called about most, with canonicals still pointing at the staging domain a close second. Neither shows up as an error anywhere; the site simply doesn’t get indexed, and the weeks pass. Both have their own row in the acceptance table below. The rest of the crawl skeleton, with what passes for each piece:
| Control | What passes |
|---|---|
| robots.txt | Blocks admin, internal search and parameter combinations; keeps CSS and JavaScript open; points to the sitemap; allows by name the search crawlers you want to be cited by (OAI-SearchBot, Claude-SearchBot, PerplexityBot), since a rule written against a training crawler doesn’t touch search and some CDNs now block AI crawlers by default |
| sitemap.xml | Generated by the CMS; lastmod changes only when the page does. Google ignores priority and changefreq and uses lastmod only when it’s consistently accurate; a deploy timestamp on every URL isn’t |
| Canonical tags | Self-referencing on unique pages, one per page, set from the CMS field |
| Staging | HTTP authentication (401) plus an X-Robots-Tag: noindex header, never robots.txt alone, which stops the crawl but not the indexing of the URL |
| HTTPS | Valid certificate; one redirect from HTTP to HTTPS, no hop through www |
Leave FAQPage off the schema list: Google restricted FAQ rich results to government and health sites in 2023 and dropped them in 2026, so marking up an FAQ block buys nothing in the results. A business site needs Organization on the homepage, Article on posts with a named author, BreadcrumbList everywhere, and Product, Service or LocalBusiness where they apply, as JSON-LD in the served HTML; Google reads JSON-LD injected by a tag manager only after rendering, and crawlers that don’t run JavaScript never see it. One URL per template goes through the Rich Results Test and the Schema.org validator before launch.
Before committing to a CMS, I check whether an editor can set, per page, without a developer: the title tag and meta description, the canonical, the H1 independent of the visual headline, the URL slug, the structured data, and a redirect when the URL changes. If any of those routes through an engineering ticket, SEO velocity is capped at the speed of the deploy queue. On headless without those fields, fixing a canonical is a deploy. Which platform to stay on or move to is a longer decision, and the stay / move / go-headless table is in Step 4 of the redesign guide.
SEO acceptance criteria: the web development definition of done
I write all of the above into the web development team’s definition of done. A template doesn’t pass review until it passes these rows, each row has a test, and each has an owner who isn’t “the SEO person.” If an agency builds the site, this table and the ownership table go into the statement of work.
| Criterion | How it’s tested | Owner |
|---|---|---|
| Primary content and internal links present in served HTML | View source contains a sentence from the main copy; Screaming Frog crawl with JavaScript off returns full text and all links | Front-end lead |
| Canonical and title parity | Canonical and title in served HTML equal the ones after hydration, on every template; one canonical per page | Front-end lead |
| Semantic markup | One H1, heading outline in order, links as <a href>, images sized with alt, LCP image not lazy-loaded; axe or Lighthouse accessibility pass with no critical issues | Front-end lead |
| Editor controls the SEO primitives | A marketer sets title, description, canonical, H1, slug, schema and a redirect on a test page without a ticket | CMS / platform |
| Core Web Vitals per template | LCP under 2.5 s, INP under 200 ms, CLS under 0.1 in the lab on a throttled mid-range phone; third-party script inventory signed off; field data reviewed at 30 days | Performance |
| robots.txt and sitemap | Staging blocked with 401 + X-Robots-Tag; production allows Googlebot and the search agents by name; sitemap index under the 50,000-URL limit with accurate lastmod | DevOps |
| Production free of staging controls | On launch day, a crawl of production finds no noindex in meta or headers, every canonical on the production domain, the production robots.txt deployed | DevOps |
| Structured data | Organization, BreadcrumbList and the page-type schema in served HTML, valid in the Rich Results Test and the Schema.org validator, matching visible content | Front-end lead |
| Launch content scored | Every page in the launch set passes an information-gain check against the pages already ranking for its query | Content |
| Tracking live before launch | Search Console domain property verified through DNS, sitemap submitted, GA4 key events firing on staging, event retention set to 14 months, rank tracker loaded with the keyword map | Marketing ops |
The owners are roles inside the two columns of the ownership table: front-end lead, DevOps and CMS / platform sit on the development side; content and marketing ops sit on the SEO side. The row engineering teams push back on is the launch content, because it isn’t code. It stays. Google says its core systems assess pages mostly one by one and also use site-wide signals, and a launch set padded with templated pages is the kind of signal I don’t want a new domain to start with. My team writes the first batch during development and scores each piece before it publishes; a page that reads as a rehash of what already ranks doesn’t go live.

Timelines by project size
None of this is a rule, but after enough builds where web development and SEO ran as one process the shapes repeat, and content stretches the longer ones more than code does.
| Project size | Duration | Where the SEO work sits |
|---|---|---|
| Small, 10–20 pages | 2–4 weeks | Keyword map and architecture in week one; templates built against the acceptance table; one pre-launch pass |
| Mid-size, 50–200 pages | 6–8 weeks | Stakeholder sign-off on the ownership table first; content model and templates; launch content written while the build runs |
| Enterprise, 500+ pages | 12+ weeks | Tech specs before the first sprint; two development phases, with the structured-data row deferred to the second; a phased launch with per-template monitoring |
Web development mistakes that hurt SEO
Most web development and SEO mistakes are rows of the acceptance table, missed:
- Client-side rendering on pages that need to rank. Late to Google, invisible to crawlers that don’t run JavaScript.
- Client-side routing without
href. Crawled with JavaScript off, the site has pages and no links between them. - A staging noindex shipped to production, or a canonical still pointing at the staging domain.
- The lazy-loaded hero. One attribute, and the LCP element is the last thing to load.
- Third-party scripts nobody inventoried. Chat, consent, heatmaps, three tag managers, and INP fails on the sum.
- Two canonicals on one page, from two plugins, or from a component and a template on a headless stack, so Google resolves the conflict for you.
- A CMS the marketer can’t edit. Title, slug and redirect changes queue behind feature work, and the keyword map never becomes pages.
- FAQ markup for a rich result that no longer exists.
- Launching with no Search Console and no analytics, so for the first weeks there is nothing to read.
My bet for the next two years: by 2028 the view-source test will sit in front-end teams’ definition of done the way the accessibility audit does now, and “it ranks on Google but no assistant has ever cited it” will be the diagnosis that ends the client-side-rendering argument for marketing sites for good.
Web development and SEO FAQ
Is SEO part of web development?
Half of it is. Of the seven decisions in the ownership table, four are settled in code: URL routing, rendering, performance budget and crawl controls. The other three, which pages exist, what each is titled, what gets indexed, are SEO’s and only reach the site through the CMS development built. Web development and SEO are one process in the sense that neither half can be checked without the other; the acceptance table is where the two halves get signed off together.
Does client-side rendering hurt SEO?
Unevenly. Google renders the page on a delay it doesn’t put a number on, so time-sensitive content can be stale before it’s indexed, and the AI crawlers that don’t render see nothing at all. Content that has to rank or be cited goes in the server HTML.
Which CMS is best for SEO?
The one whose editor can set title, description, canonical, H1, slug, schema and a redirect per page without a developer. WordPress with a good SEO plugin does that with the most depth and the most plugin sprawl, Webflow natively with thinner schema, headless only after someone builds the fields. Choose against who runs SEO day to day, and decide before the build: moving CMS after launch is a redesign with a migration attached.