Corporate site · Media production
La JunglaA production studio site with services, a show lineup and a blog that works for sales
Site for a digital production studio in Guayaquil: 7 service pages, 8 show pages and a 48-article blog, migrated from Next.js to Astro.
Technologies
- Astro 5
- React 19
- TypeScript
- Tailwind CSS v4
- Motion
- GSAP
- Astro Content Collections
- @astrojs/sitemap
- Docker + nginx
- Railway
- Google Analytics 4
- Microsoft Clarity

48
blog articles
8
show pages
7
service pages
67
sitemap URLs
My role
Development of the site at Azirgo SAS: the first Next.js version, the migration to Astro, the blog, the show pages and the technical SEO.
The problem
La Jungla does two things at once: it sells production - podcasts, streaming, live shopping, online courses, social content, studio rental - and it produces its own lineup of shows. Those are two different audiences: the company searching for “production studio in Guayaquil” or “how much does it cost to produce a podcast”, and the audience that wants to know which show airs today. The first version was an animated home plus a shows page, with no per-service pages and no content answering those searches.
What I built
- An editorial home with real studio photography: services, a behind-the-scenes gallery, shows, a trust block, FAQ and contact.
- Seven service landings - podcast production, studio rental, social media content, personal brand content, live shopping, live streaming and online courses - each with tabs to the other services.
- A services dropdown menu with a thumbnail and description for each one.
- A shows page and eight show pages of their own, with schedule, cover, a link to the YouTube channel, the show's own site when it has one, and FAQ.
- A lineup band on the home: the show logos ordered Monday to Sunday with their premiere day and time, in a carousel that pauses on hover and stays still when the visitor prefers reduced motion.
- A 48-article blog in seven categories, with pagination, FAQ on every article and related articles.
- Contact with WhatsApp, email and map, plus a floating WhatsApp button on every page that puts the URL the visitor is writing from into the message.
- Structured data: Organization and ProfessionalService with a service catalog, LocalBusiness with opening hours, CreativeWorkSeries for each show, Service, Article, FAQPage, BreadcrumbList and ContactPage.
How it's structured
Astro 5 with static output and React only where there is animation, mounted as islands. Shows and services are typed data modules that each feed one dynamic route, and the blog is a Markdown content collection with a validated schema. The build is served by nginx inside Docker on Railway.
- Home (/): hero, manifesto, services, behind-the-scenes gallery, lineup band, shows, trust, FAQ and contact.
- Services: /servicios/produccion/[servicio], seven landings generated from one data module per service.
- Shows: /programas and /programas/[slug], eight pages read from a single show registry.
- Blog: /blog, /blog/[slug] and /blog/page/[n], with the 20-per-page pagination marked noindex and kept out of the sitemap.
- Contact: /contacto with WhatsApp, email, location and a map injected only when needed; plus a custom 404.
- Content model: each article is a .md file with title, optional SEO title, description, dates, category, cover, keywords, FAQ and CTA, validated with Zod.
- Shared data: the show registry feeds the lineup band, the home grid, each show page, its FAQ and its JSON-LD.
- Measurement and integrations: GA4 and Microsoft Clarity with deferred loading, floating WhatsApp on every page, and security and cache headers defined in nginx.
A blog that works for the services
The 48 articles are not an appendix: each blog category backs a service landing, and the linking runs both ways.
- Seven categories - Podcast, Live Shopping, Personal Brand, Streaming, Courses, Social Content and Production Studio - aligned with the services.
- Each service landing lists the articles on its topic, newest first; before, the pillar did not link down and the articles hung only off the pagination.
- Each article ends with three related articles, same-category ones first.
- All 48 carry an FAQ, shown on the page and emitted as FAQPage from the same frontmatter.
- An optional SEO title per article keeps a long, hook-driven H1 without Google truncating it in the results.
- Real lastmod in the sitemap: each article's publication or revision date and each static page's source-file date, instead of a shared build date.
- og:image always at 1200×630: a script derives a sharing version from every cover, because the originals were arriving cropped on WhatsApp, LinkedIn and X.
Inside the site

Shows page with La Jungla's lineup. 
Podcast production service landing.
Technical decisions
- Astro with static output and React only in islands: the site is mostly content, so the HTML comes ready from the build, and the animated components that already existed were mounted as islands instead of being rewritten.
- Shows and services as typed data registries, with one dynamic route each: adding a show means adding an entry, and that entry feeds the lineup band, the grid, the show page, its FAQ and its JSON-LD.
- The visible FAQ and the FAQPage always come from the same data - on the home, on every show and on every article - because markup that does not match what is on screen is structured spam to Google.
- WhatsApp as the main channel: the floating button carries the page's canonical URL inside the message, so the team knows where each contact came from and WhatsApp shows that page's preview.
- GA4 and Clarity load on the visitor's first interaction or 8 seconds after load, with events queued in the meantime: measurement does not compete with the first render.
- An explicit AI-bot policy in robots.txt - answer engines and training crawlers, bot by bot - plus an llms.txt with services, shows and articles: the business lives on being found.
Challenges
- Migrating from Next.js to Astro without redoing the interface: a custom drop-in replacement for next/image let the existing components mount as islands untouched.
- Performance: inline CSS had grown to ~83 KB per page, Google Fonts blocked rendering for ~750 ms on mobile and the islands chained their downloads. The fix was cacheable external CSS, self-hosted fonts and parallel preloading of each island's modules.
- Shows that change name and URL: a 301 in nginx, a fallback redirect in Astro and the old routes kept out of the sitemap, so crawlers never find a redirect where they expect a page.
- Closing the SEO audit findings: a home canonical without the trailing slash, link previews cropped on 55 pages and service landings that did not link to the articles on their own topic.
Result
The site is in production with its seven service landings, eight show pages and 48 blog articles published and crawlable, 67 sitemap URLs with real modification dates, and every WhatsApp contact arrives with the page it was sent from.