DEV Community

Știuriuc Sorin-Marian
Știuriuc Sorin-Marian

Posted on

Auditing a Next.js Salary Calculator After a 4.5x Search Visibility Spike

At the end of June, a Romanian salary calculator I built entered a very different search environment.

Google Search Console showed roughly 4.5 times more impressions and clicks during the next 28-day period:

Period Clicks Impressions CTR Weighted position
June 1–28, 2026 495 41,281 1.20% 8.94
June 29–July 26, 2026 2,237 184,388 1.21% 7.77

That is a 351.9% increase in clicks and a 346.7% increase in impressions.

It would make a great case study if I could honestly say: “I changed a few tags, Google rewarded the site, and traffic exploded.”

That is not what happened.

The more useful story is how I audited the site after the spike, separated seasonal demand from technical improvements, and decided what not to change while the data was still incomplete.

The project is salariile.ro, a Next.js and TypeScript calculator for Romanian salaries and payroll taxes.

The first clue was the nearly unchanged CTR

Clicks grew by 4.52x. Impressions grew by 4.47x. CTR moved from 1.20% to 1.21%.

That pattern matters.

If the increase had primarily come from dramatically better titles, snippets, or rankings, I would expect a clearer CTR change. Instead, Google showed the site much more often, and clicks increased almost proportionally.

There was a ranking improvement: weighted average position moved from 8.94 to 7.77. That is useful progress, especially around the first results page, but it does not explain a four-and-a-half-fold increase by itself.

The stronger explanation was external demand.

Romania’s statutory minimum gross salary changed from 4,050 lei to 4,325 lei on July 1, 2026. That created a predictable wave of searches around:

  • the new minimum net salary;
  • employer costs;
  • payroll tax calculations;
  • gross-to-net conversions;
  • the effective date of the change.

The comparison window starts on June 29, immediately before the change. It therefore captures the search peak around a national fiscal event, while the previous period does not.

SEO improvements may have helped the site capture some of that demand. They did not create the demand.

That distinction changes how I interpret every metric that follows.

What we cannot conclude

This dataset does not prove that a particular deployment caused the increase.

It does not provide a clean experiment, because several variables changed at once:

  • search demand rose sharply around July 1;
  • the query mix changed;
  • Google crawled and reevaluated pages on its own schedule;
  • some site improvements were deployed during or after the peak;
  • Search Console data was not fully finalized through the audit date.

When I ran the analysis on July 29, the latest final Search Console date was July 26. Changes made close to that date did not yet have a complete post-deployment observation window.

A responsible conclusion is:

The site gained substantially more visibility during a major seasonal event, while average position improved and CTR remained almost flat.

A less responsible conclusion would be:

Our latest SEO changes increased organic traffic by 352%.

I am waiting for complete seven-, fourteen-, and twenty-eight-day post-change windows before attributing results to specific work.

1. SSR is an indexability requirement, not just an architecture choice

A calculator is naturally interactive, so it is easy to push too much of it into client-side rendering.

That can produce a page whose browser experience looks correct while its initial HTML contains little more than controls, placeholders, or a loading state.

For the important landing pages, I want the server-rendered response to contain:

  • the page title and primary heading;
  • an explanation of the calculation;
  • the current fiscal values;
  • useful results or examples;
  • internal links;
  • canonical and structured-data signals.

JavaScript should enhance the calculator. It should not be responsible for creating the entire indexable document.

The practical test is simple: fetch the production URL and inspect the returned HTML before hydration. If its main subject is not understandable there, the page is not finished from an SEO perspective.

2. Dynamic routes need an indexation policy

Salary calculators can generate almost unlimited combinations. A route such as /calculator/[value] could theoretically create a page for every possible salary.

That does not mean every value deserves an indexable URL.

Thousands of near-identical pages would fragment internal authority, consume crawl attention, and create little unique value. The project therefore uses an allowlist for salary-value landing pages.

A simplified Next.js pattern looks like this:

const indexedSalaryValues = [4050, 4325, 5000, 10000];

export function generateStaticParams() {
  return indexedSalaryValues.map((value) => ({
    value: String(value),
  }));
}
Enter fullscreen mode Exit fullscreen mode

The exact implementation is less important than the rule: a new indexable value must have demonstrated search demand or a distinct fiscal purpose.

Users can still calculate arbitrary salaries interactively. User input simply does not create an unlimited indexable URL inventory.

3. Canonicals should be tested as contracts

Every indexable page emits a self-referencing canonical.

That sounds basic, but canonical regressions often appear during route refactors, metadata abstraction, query-string handling, or trailing-slash changes.

I do not treat “the component contains a canonical declaration” as sufficient. The rendered production output should answer three questions:

  1. Is the canonical present?
  2. Does it resolve to the intended public URL?
  3. Is that URL indexable and successful?

A canonical pointing to a redirect, a different salary variant, or the wrong hostname can quietly undermine an otherwise good page.

4. Rendered tests catch SEO failures that unit tests miss

Calculation tests verify fiscal logic. They do not verify what a crawler receives.

The project also tests rendered routes for SEO-critical output, including:

  • HTTP status;
  • title and description;
  • one meaningful H1;
  • canonical URL;
  • indexability;
  • expected content;
  • valid JSON-LD;
  • treatment of unsupported calculator values.

This turns important SEO behavior into a regression boundary.

If a refactor accidentally removes an H1, changes a canonical, or makes a fiscal page render an empty client shell, the test should fail before deployment.

5. JSON-LD is useful only when it describes the visible page

Structured data is not a place to list every schema type that might generate a rich result.

The site uses page-appropriate entities such as WebApplication, Article, FAQPage, BreadcrumbList, WebPage, and Organization.

The rules I follow are:

  • the markup must parse;
  • the type must match the page;
  • claims must agree with visible content;
  • dates and URLs must be consistent;
  • FAQ markup must correspond to questions users can actually read.

Schema validation passing is necessary, but it is not evidence that the page deserves stronger rankings.

6. Crawl the live deployment, not only the repository

The production crawl covered all 63 URLs present in the live sitemap.

The result was 63 successful responses out of 63, with:

  • no missing or mismatched canonicals;
  • no accidental noindex;
  • no invalid JSON-LD;
  • no missing primary headings;
  • no duplicate titles or descriptions;
  • no true orphan pages;
  • no unexpectedly thin pages under the audit threshold.

That is a useful technical baseline. It is not an SEO victory by itself.

A perfectly crawlable page can still rank poorly because its content is less useful, its intent is unclear, its result is unattractive, or competing domains have much stronger authority.

7. Keep Core Web Vitals in the release gate

Markup and crawlability are only part of the audit.

For Core Web Vitals, I monitor:

  • LCP for delayed hero content, fonts, and render-blocking assets;
  • INP for calculator interactions and expensive client-side handlers;
  • CLS for results, notices, and controls that shift after hydration.

Field data and lab data serve different purposes. Lab runs are excellent regression alarms, while field data shows what real users experience at the 75th percentile.

I do not use a green Lighthouse run to explain an organic traffic spike. Likewise, I would not ignore a real-user performance regression just because rankings had not moved yet.

Performance is a product-quality requirement first and a search signal second.

Why the next bottleneck is probably off-page

The audit did not uncover a technical failure large enough to explain the remaining ranking ceiling.

Several high-volume generic queries sit around positions 6–10. The strongest pages already have sound rendering, canonicals, internal linking, structured data, and substantial content.

At that point, repeatedly rewriting healthy pages can create more risk than value.

The larger gap is external authority: relevant websites independently citing the project as a useful source.

The next phase is therefore not mass link building. It is producing assets that deserve references:

  • transparent calculation methodology;
  • reusable fiscal tables and datasets;
  • reproducible examples;
  • an embeddable calculator or widget;
  • original analyses that HR, accounting, and employment publications can verify.

The project’s methodology page exists so readers can inspect assumptions and official sources rather than trust an unexplained number.

For developers who want to inspect the implementation, the repository is public on GitHub.

Relevant editorial citations are useful. Purchased links, automated directory submissions, and unrelated guest-post networks are not a durable strategy, especially for salary and tax information.

My post-spike audit checklist

When a search spike appears, I now ask:

  • Did clicks grow faster than impressions?
  • Did CTR or average position materially change?
  • Was there a seasonal, legal, or news event?
  • Is the latest Search Console data final?
  • Does the initial HTML contain the page’s real content?
  • Are dynamic indexable URLs intentionally limited?
  • Do rendered pages pass canonical, heading, schema, and status tests?
  • Are Core Web Vitals healthy in field data?
  • Is the bottleneck still technical, or has authority become the limiting factor?
  • What observation window is required before making another change?

The hardest SEO decision can be to wait

A large spike creates pressure to optimize everything immediately.

In this case, the better decision is to preserve the strongest pages, document the baseline, and wait for complete post-event data. The homepage remains the owner of the generic calculator intent until the seasonal wave normalizes and there is enough evidence to justify any migration.

The audit confirmed that the technical foundation is healthy.

It also showed why that is not enough.

Search growth came from the intersection of real-world demand, crawlable implementation, useful content, and improving visibility. The next challenge is earning enough trust outside the site to move important queries from the lower half of page one into the positions where people actually click.

Top comments (0)