Conversation
|
Visit the preview URL for this PR (updated for commit b0a08d2): https://sunnytechwebsite--pr57-add-sponso-banner-gg3l9uxl.web.app (expires Tue, 21 Apr 2026 15:15:18 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: b96ac7ab85879442bb94dc448b41aeca0f34d16c |
65e3fd1 to
7d496b0
Compare
Signed-off-by: Louis Labeyrie <labeyrielouis@gmail.com>
7d496b0 to
2024b69
Compare
There was a problem hiding this comment.
Pull request overview
Adds a sponsor banner to the site layout, driven by OpenPlanner sponsor metadata, so selected sponsors can be highlighted globally.
Changes:
- Extend the
Sponsortype to includecustomFields. - Fetch OpenPlanner data in
Layout.astroand computebannerSponsorsbased oncustomFields['option-comm']. - Add a new
SponsorBanner.astrocomponent that renders sponsor logos and hides on scroll.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
| src/type.ts | Adds customFields to the Sponsor interface to support banner selection. |
| src/layouts/Layout.astro | Fetches OpenPlanner data in the base layout and injects the SponsorBanner. |
| src/components/SponsorBanner.astro | New component to render the sponsor banner UI and scroll-hide behavior. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| } | ||
|
|
||
| const { title, description, metaImage } = Astro.props | ||
|
|
||
| const response = await fetch(OPENPLANNER_URL) | ||
| const openPlannerData: OpenPlannerType = await response.json() | ||
| const bannerSponsors = openPlannerData.sponsors.flatMap((cat) => | ||
| cat.sponsors.filter((s) => s.customFields?.['option-comm'] === true) | ||
| ) |
There was a problem hiding this comment.
Fetching OpenPlanner data inside the base Layout introduces duplicated network calls on pages that already fetch the same data (e.g. src/pages/index.astro, jobs.astro, schedule/speaker pages). This can significantly increase build time / external API load. Consider deduplicating via a shared getOpenPlannerData() helper with module-level caching, or by passing the already-fetched data (or computed bannerSponsors) into Layout as an optional prop so each page performs at most one fetch.
| } | |
| const { title, description, metaImage } = Astro.props | |
| const response = await fetch(OPENPLANNER_URL) | |
| const openPlannerData: OpenPlannerType = await response.json() | |
| const bannerSponsors = openPlannerData.sponsors.flatMap((cat) => | |
| cat.sponsors.filter((s) => s.customFields?.['option-comm'] === true) | |
| ) | |
| bannerSponsors?: OpenPlannerType['sponsors'][number]['sponsors'] | |
| } | |
| const { title, description, metaImage, bannerSponsors: providedBannerSponsors } = Astro.props | |
| const bannerSponsors = | |
| providedBannerSponsors ?? | |
| (await (async () => { | |
| const response = await fetch(OPENPLANNER_URL) | |
| const openPlannerData: OpenPlannerType = await response.json() | |
| return openPlannerData.sponsors.flatMap((cat) => | |
| cat.sponsors.filter((s) => s.customFields?.['option-comm'] === true) | |
| ) | |
| })()) |
| window.addEventListener('scroll', () => { | ||
| const banner = document.querySelector('#sponsor-banner') as HTMLElement | null | ||
| if (banner) { | ||
| banner.classList.toggle('hidden', window.scrollY > 0) | ||
| } | ||
| }) |
There was a problem hiding this comment.
SponsorBanner.astro always registers a scroll event listener even when there is no banner rendered (when sponsors.length === 0), and it does a querySelector on every scroll. Consider only attaching the listener when the banner exists (or when sponsors.length > 0), caching the banner element outside the handler, and using a passive listener to reduce scroll overhead.
| window.addEventListener('scroll', () => { | |
| const banner = document.querySelector('#sponsor-banner') as HTMLElement | null | |
| if (banner) { | |
| banner.classList.toggle('hidden', window.scrollY > 0) | |
| } | |
| }) | |
| const banner = document.querySelector('#sponsor-banner') as HTMLElement | null | |
| if (banner) { | |
| const handleScroll = () => { | |
| banner.classList.toggle('hidden', window.scrollY > 0) | |
| } | |
| handleScroll() | |
| window.addEventListener('scroll', handleScroll, { passive: true }) | |
| } |
Show "et X autre(s) sponsor(s)" after logos, excluding partners from the count.
- Wrap OpenPlanner fetch in try/catch with fallback to empty list (Copilot suggestion) - Use template literal for "et X autres sponsors" to prevent prettier from splitting the expression across lines and adding unwanted whitespace
Cache banner ref outside handler and use passive listener for better scroll performance.

No description provided.