Skip to content

fix(landing): fix oversized HTML and severe LCP on integration/comparison pages#5634

Merged
waleedlatif1 merged 3 commits into
stagingfrom
seo-html-size-lcp-fixes
Jul 13, 2026
Merged

fix(landing): fix oversized HTML and severe LCP on integration/comparison pages#5634
waleedlatif1 merged 3 commits into
stagingfrom
seo-html-size-lcp-fixes

Conversation

@waleedlatif1

Copy link
Copy Markdown
Collaborator

Summary

  • Fixed /integrations/slack at 5.2MB (over Googlebot's 2MB crawl limit) - the "Agent templates" section rendered every template matching the block type with no cap; Slack is referenced in 445 templates (vs 52-126 for Salesforce/Gmail/HubSpot) since it's a common notification target. Capped to 12, matching the same file's existing related-integrations cap of 4
  • Fixed /integrations at 1.83MB (right at the limit) - the client-side search grid received the full Integration[] (including every integration's complete operations/triggers arrays) just to build a search index. Added IntegrationSummary/toIntegrationSummary to precompute a single searchable string server-side instead, dropping 77% of the embedded per-item payload while keeping the same search behavior (name, description, operation names, trigger names)
  • Both fixes turned out to also fix severe LCP (9-10s) on /integrations/hubspot, /comparison/flowise, and /integrations/hugging-face - shrinking the integrations grid's client bundle reduced a shared chunk loaded across landing pages more broadly than expected
  • Checked /integrations/salesforce, /integrations/gmail, /integrations/amazon-dynamodb, /comparison/tines, and the flagged models page - already healthy, no changes needed

Type of Change

  • Bug fix
  • Performance improvement

Testing

Verified via a real production build + curl for actual HTML byte size, and Lighthouse (mobile, devtools throttling) against both live production and the fixed local build:

  • /integrations: 1.83MB → 1.31MB, Performance 47 → 96, LCP → 2.1s, TBT 2,770ms → 110ms
  • /integrations/slack: 5.2MB → 355KB (93% reduction), Performance 47 → 96, LCP 9.7s → 1.9s
  • /integrations/hubspot: 901KB → 452KB, Performance 72 → 97, LCP 9.1s → 1.9s
  • /integrations/hugging-face: Performance 72 → 95, LCP 9.2s → 2.3s (reproduced twice on production before fixing)
  • /comparison/flowise: Performance 71 → 95, LCP 9.8s → 2.1s

Checklist

  • Code follows project style guidelines
  • Self-reviewed my changes
  • Tests added/updated and passing
  • No new warnings introduced
  • I confirm that I have read and agree to the terms outlined in the Contributor License Agreement (CLA)

…ison pages

Google Search Console flagged /integrations, /integrations/slack, and
several others for exceeding Googlebot's 2MB uncompressed-HTML crawl
limit, plus severe LCP on /integrations, /integrations/slack,
/integrations/hubspot, /comparison/flowise, and /integrations/hugging-face.

Root cause 1 - /integrations/slack was 5.2MB (measured on production).
The "Agent templates" section renders every template matching
getTemplatesForBlock(type) with no cap - Slack is referenced as
alsoIntegrations in 445 templates (vs 52-126 for Salesforce/Gmail/
HubSpot), so its detail page embedded hundreds of full template cards
in the initial HTML/RSC payload. Capped to 12, consistent with the
same file's existing related-integrations cap of 4.

Root cause 2 - /integrations was 1.83MB, right at the limit. The client
IntegrationGrid component receives the full Integration[] as props
(needed for instant client-side search), which serializes every
integration's complete operations/triggers arrays - including full
per-operation description sentences - into the initial payload purely
to build a search index. Added IntegrationSummary + toIntegrationSummary
(lib/integrations): the same searchable surface (name, description,
operation names, trigger names) precomputed server-side into one
lowercased string, dropping the full operations/triggers data the
client never actually renders. Measured: 627KB -> 142KB of embedded
integration data (77% reduction).

Verified via a real production build + curl:
- /integrations: 1.83MB -> 1.31MB
- /integrations/slack: 5.2MB -> 355KB (93% reduction)
- /integrations/hubspot: 901KB -> 452KB

Verified via Lighthouse (mobile, devtools throttling, matching what
real users on a typical device experience) against both live production
and the fixed local build:
- /integrations: 47 -> 96 (LCP unmeasured->2.1s, TBT 2,770ms->110ms)
- /integrations/slack: 47 -> 96 (LCP 9.7s -> 1.9s)
- /integrations/hubspot: 72 -> 97 (LCP 9.1s -> 1.9s)
- /integrations/hugging-face: 72 -> 95 (LCP 9.2s -> 2.3s, reproduced
  twice on production before fixing - not a fluke)
- /comparison/flowise: 71 -> 95 (LCP 9.8s -> 2.1s)

The last two aren't Slack-style template-count outliers (4 and 0
alsoIntegrations references respectively) - shrinking the shared
IntegrationGrid client bundle appears to have reduced a shared chunk
loaded broadly across landing pages, benefiting pages beyond the ones
directly touched.

Also checked and confirmed already healthy, no action needed:
/integrations/salesforce, /integrations/gmail, /integrations/amazon-dynamodb,
/comparison/tines, /models/xai/grok-4-20-multi-agent-0309.
@vercel

vercel Bot commented Jul 13, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Skipped Skipped Jul 13, 2026 6:08pm

Request Review

@cursor

cursor Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR Summary

Low Risk
Landing-only presentation and payload shaping; search semantics are preserved via precomputed searchFields and template sort/cap logic.

Overview
Shrinks landing integration pages so HTML/RSC stays under crawl limits and client bundles are lighter, with no intended change to search or template UX beyond what’s shown.

On /integrations/[slug], agent templates are limited to 12 after sorting featured first, then templates owned by the integration (isOwner from getTemplatesForBlock), so high-connectivity pages (e.g. Slack via alsoIntegrations) no longer embed hundreds of template cards.

On /integrations, the client grid no longer receives full Integration objects (operations, triggers, landing metadata). Server-side toIntegrationSummary / IntegrationSummary precomputes searchFields for the same per-field search behavior; featured cards and IntegrationGrid use summaries only.

getTemplatesForBlock now sets isOwner on ScopedBlockTemplate to support that sort order.

Reviewed by Cursor Bugbot for commit 27243e9. Configure here.

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reduces oversized landing-page payloads for integration pages and the integrations catalog.

  • Caps the templates shown on integration detail pages.
  • Prioritizes featured templates before applying the cap.
  • Adds compact integration summaries for the catalog grid.
  • Moves catalog search to precomputed per-field search data.

Confidence Score: 5/5

This looks safe to merge.

  • No blocking issues found in the changed code.

Important Files Changed

Filename Overview
apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx Adds a capped template list and sorts featured templates before slicing.
apps/sim/blocks/registry.ts Adds ownership metadata to scoped block templates.
apps/sim/lib/integrations/index.ts Adds compact integration summaries with precomputed search fields.
apps/sim/app/(landing)/integrations/components/integration-grid.tsx Uses compact summaries and per-field search data in the catalog grid.

Reviews (4): Last reviewed commit: "fix(landing): sort featured templates ah..." | Re-trigger Greptile

Comment thread apps/sim/lib/integrations/index.ts Outdated
Comment thread apps/sim/lib/integrations/index.ts
Comment thread apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx
@greptile-apps

greptile-apps Bot commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR reduces payload size on the integrations landing pages. The main changes are:

  • Caps rendered templates on individual integration pages.
  • Sends compact integration summaries to the client grid.
  • Precomputes catalog search text on the server.
  • Narrows the integration card and grid props to the summary shape.

Confidence Score: 4/5

The integrations search path needs a small fix before merging.

  • The payload reduction and prop narrowing are consistent with the changed callers.
  • The new precomputed search text drops operation and trigger description matches.
  • Users can receive fewer results for queries that worked before.

apps/sim/lib/integrations/index.ts

Important Files Changed

Filename Overview
apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx Adds a fixed cap for rendered templates on integration detail pages.
apps/sim/app/(landing)/integrations/(shell)/page.tsx Builds integration summaries and passes them into the client grid.
apps/sim/app/(landing)/integrations/components/integration-card.tsx Narrows card props to the fields used by landing integration cards.
apps/sim/app/(landing)/integrations/components/integration-grid.tsx Filters compact integration summaries using precomputed search text.
apps/sim/lib/integrations/index.ts Adds toIntegrationSummary, but its search text omits fields previously searched by the grid.
apps/sim/lib/integrations/types.ts Adds the compact IntegrationSummary type for landing-page grid data.

Reviews (2): Last reviewed commit: "fix(landing): fix oversized HTML and sev..." | Re-trigger Greptile

Comment thread apps/sim/lib/integrations/index.ts Outdated
Comment thread apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx Outdated
Comment thread apps/sim/lib/integrations/index.ts
Two real regressions from the previous commit, both confirmed by
Greptile and Cursor Bugbot independently:

- lib/integrations: IntegrationSummary.searchText joined every field
  into one string, so (a) it dropped operation/trigger descriptions
  entirely (a search for API-specific terms that only appear in an
  operation's description, not its name, silently stopped matching),
  and (b) a single joined string lets a query span a field boundary
  (e.g. matching across the tail of a name and the head of the next
  field) that the original per-field search never allowed. Reverted to
  a searchFields array - same content as the original per-field index
  (name, description, every operation's name+description, every
  trigger's name), just precomputed server-side instead of shipping
  the full Integration objects. Grid filtering goes back to
  `.some(field => field.includes(q))`, matching the exact original
  matching semantics.
- blocks/registry.ts + integrations/[slug]/page.tsx: capping
  getTemplatesForBlock's result with a plain .slice(0, 12) kept
  whatever 12 templates happened to iterate first in registry
  insertion order - for a high-connectivity integration like Slack,
  that can be entirely alsoIntegrations matches from unrelated blocks,
  silently dropping the integration's own owned templates and any
  marked featured. Added an explicit isOwner flag to
  ScopedBlockTemplate (the registry function already computes this
  internally, just wasn't surfacing it) and sort owner-first,
  featured-second before slicing.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

Comment thread apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx Outdated

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit ec28a58. Configure here.

…iebreaker

The previous sort (owner-first, featured as a tiebreaker within each
owner tier) meant an integration with 12+ owned templates filled the
entire cap with non-featured owned templates before any featured
related template (reached via alsoIntegrations) was ever considered -
Slack hits this case. Swapped the sort so featured (owned or related)
ranks first, then owned-but-not-featured, so a curated featured
template can no longer be sliced away by a pile of ordinary owned ones.
@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@greptile

@waleedlatif1

Copy link
Copy Markdown
Collaborator Author

@cursor review

@cursor cursor Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

✅ Bugbot reviewed your changes and found no new issues!

Comment @cursor review or bugbot run to trigger another review on this PR

Reviewed by Cursor Bugbot for commit 27243e9. Configure here.

@waleedlatif1 waleedlatif1 merged commit 8ae3538 into staging Jul 13, 2026
18 checks passed
@waleedlatif1 waleedlatif1 deleted the seo-html-size-lcp-fixes branch July 13, 2026 18:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant