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

vercelBot commented Jul 13, 2026

Copy link
Copy Markdown

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

1 Skipped Deployment
ProjectDeploymentActionsUpdated (UTC)
docsSkippedSkippedJul 13, 2026 6:08pm

Request Review

@cursor

cursorBot 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
CollaboratorAuthor

@greptile

@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@cursor review

@greptile-apps

greptile-appsBot 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

FilenameOverview
apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsxAdds a capped template list and sorts featured templates before slicing.
apps/sim/blocks/registry.tsAdds ownership metadata to scoped block templates.
apps/sim/lib/integrations/index.tsAdds compact integration summaries with precomputed search fields.
apps/sim/app/(landing)/integrations/components/integration-grid.tsxUses 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 threadapps/sim/lib/integrations/index.ts Outdated
Comment threadapps/sim/lib/integrations/index.ts
Comment threadapps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx
@greptile-apps

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

FilenameOverview
apps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsxAdds a fixed cap for rendered templates on integration detail pages.
apps/sim/app/(landing)/integrations/(shell)/page.tsxBuilds integration summaries and passes them into the client grid.
apps/sim/app/(landing)/integrations/components/integration-card.tsxNarrows card props to the fields used by landing integration cards.
apps/sim/app/(landing)/integrations/components/integration-grid.tsxFilters compact integration summaries using precomputed search text.
apps/sim/lib/integrations/index.tsAdds toIntegrationSummary, but its search text omits fields previously searched by the grid.
apps/sim/lib/integrations/types.tsAdds 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 threadapps/sim/lib/integrations/index.ts Outdated
Comment threadapps/sim/app/(landing)/integrations/(shell)/[slug]/page.tsx Outdated
Comment threadapps/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
CollaboratorAuthor

@greptile

@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@cursor review

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

@cursorcursorBot 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
CollaboratorAuthor

@greptile

@waleedlatif1

Copy link
Copy Markdown
CollaboratorAuthor

@cursor review

@cursorcursorBot 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 stagingJul 13, 2026
18 checks passed
@waleedlatif1
waleedlatif1 deleted the seo-html-size-lcp-fixes branch July 13, 2026 18:24
Sign up for freeto 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

@waleedlatif1