Przejdź do treści

MDX w Astro i Next.js: jak pisać artykuły z komponentami React w treści

Artykuł jako Markdown z interaktywnymi komponentami React w środku — MDX robi to bez bólu. Setup, frontmatter i typowanie treści w Astro i Next.js.

Maciej Sala

Founder StriveLab

4 min czytaniaOpublikowano 24 kwietnia 2026 (Aktualizacja 24 czerwca 2026)

to format, który łączy Markdown z komponentami JSX. W praktyce oznacza to, że w środku artykułu możesz wstawić interaktywny kalkulator, animowaną grafikę, niestandardową ramkę z ostrzeżeniem albo ankietę — bez opuszczania pliku z treścią.

Czym różni się MDX od Markdown?

Markdown to czysty tekst ze składnią dla nagłówków, list, pogrubień, linków i obrazów. MDX dodaje dwie rzeczy:

  1. Komponenty w treści — możesz napisać <Callout variant="warning">Uwaga!</Callout> w środku akapitu i to się wyrenderuje jako prawdziwy komponent.
  2. Import innych komponentów — w górze pliku możesz zaimportować React/Vue/Svelte component i użyć go jako JSX.

Przykład MDX:

Code
---
title: 'Mój wpis o Astro'
date: 2026-04-24
---
 
import Callout from '../../components/Callout.astro'
import PriceCalculator from '../../components/PriceCalculator.tsx'
 
# Astro jest szybki
 
Ale nie zawsze to oznacza, że jest dla Ciebie.
 
<Callout variant="info">
  Ten artykuł zakłada, że znasz podstawy HTML i CSS.
</Callout>
 
## Oblicz koszt projektu
 
<PriceCalculator client:visible />
 
Reszta artykułu wraca do zwykłego Markdowna. **Pogrubienie**, _kursywa_, [linki](https://example.com) — wszystko działa jak w MD.

Wynik: artykuł, w którym masz zarówno zwykłą treść, jak i niestandardowy komponent informacyjny i interaktywny kalkulator.

Jak skonfigurować MDX w Astro i Next.js?

W skrócie: w Astro MDX włączasz jedną komendą astro add mdx, w Next.js instalujesz cztery paczki, konfigurujesz createMDX w next.config.mjs i dodajesz wymagany plik mdx-components.tsx. Tu zaczyna się pierwsza różnica między frameworkami.

W Astro instalacja to jedna komenda:

Code
npx astro add mdx

To instaluje @astrojs/mdx i wpisuje integrację mdx() do astro.config.mjs. Typy dla .mdx dostajesz automatycznie przez astro/client, więc nie musisz ręcznie ruszać tsconfig.json. Pliki .mdx w src/pages/ automatycznie stają się stronami (file-based routing), a pliki w src/content/ można wciągnąć do — tak, jak opisałem w artykule o Content Collections.

W Next.js (App Router) instalujesz cztery paczki i konfigurujesz next.config.mjs przez createMDX:

Code
npm install @next/mdx @mdx-js/loader @mdx-js/react @types/mdx
Code
// next.config.mjs
import createMDX from '@next/mdx'
 
/** @type {import('next').NextConfig} */
const nextConfig = {
  pageExtensions: ['js', 'jsx', 'md', 'mdx', 'ts', 'tsx'],
}
 
const withMDX = createMDX()
 
export default withMDX(nextConfig)

Plus jeden krok, którego w Astro nie ma: mdx-components.tsx w korzeniu projektu jest wymagany — bez niego @next/mdx z App Routerem po prostu nie zadziała:

Code
// mdx-components.tsx
import type { MDXComponents } from 'mdx/types'
 
const components: MDXComponents = {}
 
export function useMDXComponents(): MDXComponents {
  return components
}

Różnica filozoficzna: w Astro .mdx to obywatel pierwszej klasy z pudełka, w Next.js MDX jest wpinany jako rozszerzenie kompilatora — stąd więcej kroków, ale i głębsza integracja z React Server Components.

Frontmatter w MDX: Astro natywnie, Next.js przez wtyczkę

MDX w Astro używa YAML — taki sam jak w zwykłym Markdownie. Pola dostępne są później jako frontmatter (w page mode) lub data (w Content Collections).

Code
---
title: 'Mój pierwszy wpis'
description: 'Opis dla SEO, 50-160 znaków.'
date: 2026-04-24
tags: ['astro', 'poradnik']
---
 
# {frontmatter.title}
 
Treść artykułu...

Zwróć uwagę na {frontmatter.title} — w MDX można używać wyrażeń JavaScript w ciałopodobnej składni JSX. To potężne narzędzie, bo pozwala DRY-ować treść (tytuł z frontmatteru użyty automatycznie).

W kontekście Content Collections rekomenduję jednak trzymać title w szablonie (<h1>{post.data.title}</h1> w [...slug].astro) i w MDX nie duplikować go. Inaczej łatwo o rozjazd.

Jakie komponenty React warto trzymać w blogu MDX?

Z doświadczenia — kilka komponentów zarabia na siebie w każdym blogu MDX. Oto te, które trzymam pod ręką.

Callout i Notice w MDX

Ramka z ostrzeżeniem, informacją lub wskazówką:

Code
---
// src/components/Callout.astro
type Variant = 'info' | 'warning' | 'danger' | 'tip';
 
interface Props {
  variant?: Variant;
}
 
const { variant = 'info' } = Astro.props;
 
const styles: Record<Variant, string> = {
  info: 'bg-blue-50 border-blue-400 text-blue-900',
  warning: 'bg-yellow-50 border-yellow-400 text-yellow-900',
  danger: 'bg-red-50 border-red-400 text-red-900',
  tip: 'bg-green-50 border-green-400 text-green-900',
};
---
 
<div class={`border-l-4 p-4 my-6 rounded ${styles[variant]}`}>
  <slot />
</div>

Nazwa propsa (variant) i wartości muszą zgadzać się z wywołaniem w MDX — to najczęstsze źródło „dlaczego mój Callout zawsze wygląda tak samo": komponent czyta jedną nazwę, a artykuł podaje inną, więc zawsze ląduje na wartości domyślnej.

Użycie w MDX:

Code
<Callout variant="warning">
  Upewnij się, że masz Node 22+ przed migracją na Astro 6.
</Callout>

Blok kodu z tytułem w MDX

Blok kodu z etykietą/tytułem:

Code
---
// src/components/CodeBlock.astro
const { filename } = Astro.props;
---
 
<div class="code-block">
  {filename && <div class="code-filename">{filename}</div>}
  <slot />
</div>
Code
<CodeBlock filename="astro.config.mjs">
 
```js
export default defineConfig({
  integrations: [mdx()],
})
```
 
</CodeBlock>

Obraz z opisem w MDX

Responsywny obraz z podpisem:

Code
---
// src/components/Figure.astro
import { Image } from 'astro:assets';
 
const { src, alt, caption } = Astro.props;
---
 
<figure class="my-6">
  <Image src={src} alt={alt} loading="lazy" />
  {caption && <figcaption class="text-sm text-gray-600 mt-2">{caption}</figcaption>}
</figure>
Code
<Figure
  src={import('../../assets/islands-diagram.png')}
  alt="Diagram architektury wysp w Astro"
  caption="Zielone prostokąty to statyczny HTML, pomarańczowe — wyspy JS."
/>

Interaktywne komponenty React w MDX

Realny przykład — prosty kalkulator osadzony w artykule o cenach:

Code
// src/components/CostCalculator.tsx
// Uwaga: w Astro NIE używasz 'use client' (to konwencja Next.js).
// Interaktywność włączasz dyrektywą client:* w miejscu użycia komponentu.
import { useState } from 'react'
 
export default function CostCalculator() {
  const [hours, setHours] = useState(10)
  const rate = 200
 
  return (
    <div className="my-6 rounded border p-4">
      <label>
        Liczba godzin:
        <input
          type="number"
          value={hours}
          onChange={(e) => setHours(+e.target.value)}
          className="ml-2 rounded border px-2 py-1"
        />
      </label>
      <p className="mt-2">
        Szacowany koszt:{' '}
        <strong>{(hours * rate).toLocaleString('pl-PL')} zł</strong>
      </p>
    </div>
  )
}
Code
import CostCalculator from '../../components/CostCalculator.tsx'
 
Ile realnie kosztuje audyt SEO? Oblicz sam:
 
<CostCalculator client:visible />

Komponent React dopiero, kiedy user doscrolluje — reszta artykułu zostaje statyczna. Jeśli temat dyrektyw hydracji jest Ci obcy, zajrzyj do artykułu o client directives.

Pamiętaj też, że w Astro 5+ React działa w wersji 19 — jeśli przenosisz komponenty ze starszego projektu, zweryfikuj zgodność bibliotek (część ekosystemu wciąż dogania React 19).

A jak to wygląda w Next.js? Dokładnie odwrotnie. Tu wszystkie komponenty są domyślnie serwerowe (React Server Components), a interaktywność włączasz dyrektywą 'use client' na górze pliku komponentu — nie przy jego użyciu w MDX:

Code
// components/CostCalculator.tsx
'use client'
import { useState } from 'react'
 
export default function CostCalculator() {
  const [hours, setHours] = useState(10)
  // ...identyczne ciało jak wyżej
}
Code
import CostCalculator from '@/components/CostCalculator'
 
Ile realnie kosztuje audyt SEO? Oblicz sam:
 
<CostCalculator />

To fundamentalna różnica jest w modelu mentalnym: Astro jest statyczny domyślnie i interaktywność dokładasz punktowo w MDX (client:*), a Next.js jest serwerowy domyślnie i interaktywność deklarujesz w pliku komponentowym (np.'use client'). Efekt jest podobny, ale osiąga się go inaczej (minimum JavaScriptu w przeglądarce). Komponenty z hookami przeglądarki w Next.js też muszą być klienckie; odpowiednikiem Astrowego client:only jest tu po prostu komponent z 'use client', który nie renderuje nic zależnego od window podczas SSR (albo next/dynamic z ssr: false).

Jak mapować elementy HTML na własne komponenty MDX?

MDX pozwala zmapować standardowe elementy HTML (np. <h2>, <a>, <img>) na własne komponenty. Używam tego do:

  • Dodawania automatycznych „anchor links" do nagłówków (kotwica obok każdego <h2>).
  • Otwierania linków zewnętrznych w nowej karcie z rel="noopener".
  • Zamiany <img> na <Image> z astro:assets dla automatycznej optymalizacji.

Ustawiasz to w layoucie artykułu:

Code
---
// src/layouts/BlogPost.astro
import AnchoredHeading from '../components/AnchoredHeading.astro';
import ExternalLink from '../components/ExternalLink.astro';
import OptimizedImage from '../components/OptimizedImage.astro';
 
const components = {
  h2: AnchoredHeading,
  h3: AnchoredHeading,
  a: ExternalLink,
  img: OptimizedImage,
};
 
const { post } = Astro.props;
const { Content } = await render(post);
---
 
<article>
  <Content components={components} />
</article>

Teraz każdy ## Nagłówek w Twoich artykułach MDX automatycznie dostaje kotwicę, każdy link zewnętrzny — target="_blank", a każdy obraz — optymalizację.

Astro nie ma wbudowanego mechanizmu, który nałożyłby to mapowanie na wszystkie pliki MDX narazcomponents przekazujesz do <Content /> przy renderowaniu. Wzorzec dla bazy z dziesiątkami artykułów nie należy do skomplikowanych, ponieważ opiera się na zdefiniowanej mapie globalnej raz w jednym wspólnym layoucie (jak wyżej) i renderowaniu przez niego każdego wpisu. Wtedy ustawienie obowiązuje wszędzie, bo wszystkie artykuły idą tą samą ścieżką renderu.

W Next.js to akurat działa wygodniej. Mapę globalną wpisujesz raz do mdx-components.tsx (tego samego pliku, który i tak jest wymagany), a Next.js stosuje ją automatycznie do każdego pliku MDX bez przekazywania czegokolwiek per-strona:

Code
// mdx-components.tsx
import type { MDXComponents } from 'mdx/types'
import Image, { type ImageProps } from 'next/image'
import { AnchoredHeading } from '@/components/AnchoredHeading'
 
const components: MDXComponents = {
  h2: AnchoredHeading,
  h3: AnchoredHeading,
  img: (props) => <Image sizes="100vw" {...(props as ImageProps)} />,
}
 
export function useMDXComponents(): MDXComponents {
  return components
}

Mapowanie lokalne (override dla jednej strony) nadal przekazujesz przez prop components do importowanego komponentu MDX, a potem scala się ono z globalnym. To jedno z miejsc, gdzie Next.js wyprzedza Astro.

Optymalizacja obrazów w MDX

Obrazy w MDX optymalizujesz przez <Image> z astro:assets (Astro) lub next/image (Next.js) zamiast surowego <img> — oba generują WebP/AVIF, responsywny srcset, leniwe ładowanie i wymuszają width/height, żeby uniknąć CLS. To obszar, gdzie MDX w Astro ma przewagę nad większością innych setupów, ponieważ zamiast pisać <img src="..."> (brak optymalizacji), używasz <Image>:

Code
import { Image } from 'astro:assets'
import heroImage from '../../assets/astro-hero.jpg'
 
<Image src={heroImage} alt="Astro logo" width={1200} height={630} />

Astro w build time:

  • Generuje wersje w WebP i AVIF.
  • Tworzy responsywne warianty (srcset).
  • Dodaje loading="lazy" dla obrazów poniżej viewportu.
  • Wstawia explicit width i height, żeby uniknąć .

Dla strony z 80+ artykułami i po kilka obrazów na każdy, automatyczna optymalizacja to różnica między 5 MB a 500 KB ładowanego contentu. Poważnie wpływa na Core Web Vitals.

W Next.js dostajesz to samo przez next/image — z tą wygodą, że mapując img w mdx-components.tsx (jak wyżej) zamieniasz każdy ![alt](src) w treści na zoptymalizowany <Image>, bez ruszania pojedynczych artykułów:

Code
import Image from 'next/image'
import heroImage from '@/assets/hero.jpg'
 
<Image src={heroImage} alt="Logo" width={1200} height={630} />

next/image generuje WebP/AVIF, responsywny srcset, leniwe ładowanie i wymusza width/height — dokładnie po to samo, co astro:assets: żeby nie płacić i wagą obrazów.

Typowana baza treści: Astro Content Collections i odpowiednik w Next.js

Najlepszy setup dla bloga to MDX z walidowanym, typowanym frontmatterem. W Astro to Content Collections. Wtedy masz:

  • Pliki .mdx w src/content/blog/.
  • Schemat Zod walidujący frontmatter.
  • Typowane pole data w szablonie.
  • Automatyczne generowanie stron dla każdego artykułu.

Konfiguracja:

Code
// src/content.config.ts
import { defineCollection } from 'astro:content'
import { glob } from 'astro/loaders'
import { z } from 'astro/zod'
 
const blog = defineCollection({
  loader: glob({ pattern: '**/*.mdx', base: './src/content/blog' }),
  schema: z.object({
    title: z.string().max(80),
    description: z.string().min(50).max(160),
    date: z.coerce.date(),
    tags: z.array(z.string()),
    image: z.string().optional(),
  }),
})
 
export const collections = { blog }

Dynamiczna strona:

Code
---
// src/pages/blog/[...slug].astro
import { getCollection, render } from 'astro:content';
import BlogLayout from '../../layouts/BlogLayout.astro';
 
export async function getStaticPaths() {
  const posts = await getCollection('blog');
  return posts.map((post) => ({
    params: { slug: post.id },
    props: { post },
  }));
}
 
const { post } = Astro.props;
const { Content } = await render(post);
---
 
<BlogLayout post={post}>
  <Content />
</BlogLayout>

Teraz każdy plik MDX dodany do src/content/blog/ automatycznie staje się stroną pod /blog/[nazwa-pliku]/ bez żadnej dodatkowej konfiguracji.

Next.js nie ma tego z pudełka — i to jest największa różnica w warstwie treści. Masz trzy ścieżki, od najprostszej do najbardziej zintegrowanej:

  • Ręcznie: fs/globby czyta pliki, gray-matter parsuje frontmatter, a Ty walidujesz go własnym schematem Zod i renderujesz w app/blog/[slug]/page.tsx przez generateStaticParams. Najwięcej kontroli, najwięcej kodu.
  • content-collections (@content-collections/mdx) — biblioteka, która daje to, co Astrowe Content Collections: typowany, walidowany Zodem frontmatter i wygodne API do listy wpisów.
  • Contentlayer — popularny historycznie, ale na 2026 jego utrzymanie jest niepewne; do nowych projektów rozważ go ostrożnie.

Schemat Zod wygląda identycznie jak w Astro — różni się tylko to, kto wczytuje pliki: w Astro robi to framework, w Next.js Ty (albo wybrana biblioteka). Mechanizm walidacji i typów jest ten sam.

Pułapki i ograniczenia MDX

1. MDX to nie jest „Markdown + HTML". To Markdown + JSX. Niektóre rzeczy wyglądające jak HTML, kompilują się jak JSX — classclassName, <br><br />, self-closing tagi. Jeśli kopiujesz HTML z innych źródeł, musisz uważać.

2. Nazwa pliku a import. W MDX importy działają względem lokalizacji pliku MDX, nie względem szablonu, który go renderuje. Jeśli przeniesiesz plik MDX do podfolderu, ścieżki importów się rozsypią.

3. Duże MDX = wolne buildy. Jeśli masz plik MDX z 50+ osadzonymi komponentami i tysiącami linii treści, buildy mogą dramatycznie zwolnić. W praktyce nie spotkałem tego problemu przy rozsądnym użyciu (3-5 osadzonych komponentów na artykuł), ale warto mieć to z tyłu głowy.

4. HMR ma limity. W dev mode edycja frontmatteru odświeża stronę w pełni, edycja treści zazwyczaj działa hot. Edycja importowanych komponentów — refresh jest konieczny.

5. Syntax highlighting. Astro używa dla bloków kodu w wersji standardowej. W Next.js dokładasz go jako wtyczkę rehype (rehype-pretty-code oparte o Shiki) w createMDX. W obu przy bardzo dużych artykułach z dziesiątkami bloków kodu rośnie czas buildu: w Astro pomaga expressive-code (lepsze caching), w Next.js warto trzymać highlighting na etapie buildu, a nie runtime.

Standardowy zestaw komponentów MDX dla bloga

W moich projektach blogowych mam standardowy zestaw komponentów:

  • <Callout> — ramka z info / warning / tip,
  • <Figure> — obraz z podpisem i optymalizacją,
  • <VideoEmbed> — lazy-loaded embed YouTube/Vimeo,
  • <CodeBlock> — kod z nazwą pliku i przyciskiem „Copy",
  • <TableOfContents> — automatyczny spis treści,
  • <RelatedArticles> — komponent z powiązanymi artykułami (przekazywany z szablonu).

Jest ich więcej, ale stosuje je w różnych konfiguracjach. Żaden z nich nie jest przesadnie skomplikowany, a każdy to 20–50 linii. Wszystkie razem sprawiają, że piszę artykuły dwa, trzy razy szybciej, a do tego spójniej.

Zasady użycia komponentów React w treści MDX

MDX bardzo łatwo zmienić w przypadkową aplikację ukrytą w artykule. Żeby tego uniknąć, trzymam się kilku zasad:

  • Komponent w MDX powinien wzmacniać zrozumienie treści, a nie zastępować normalny akapit. Nie wciskaj nic na siłę.
  • Interaktywny komponent musi mieć jasny powód biznesowy albo edukacyjny. Wszystko musi wynikać z artykułu.
  • Komponenty powtarzalne trzymaj globalnie, a nie jako jednorazowe importy w każdym wpisie.
  • Nie osadzaj ciężkich bibliotek w artykule bez lazy loadingu (client:visible w Astro, next/dynamic w Next.js).
  • Każdy custom component musi mieć sensowną wersję bez JavaScriptu albo fallback.
Ultraszybkie projekty, łączące lekkość ze skalowalnością.
Astro

Często zadawane pytania

Czym różni się MDX 2 od MDX 3?

MDX 3 (używany w Astro 5+) ma lepszą obsługę komentarzy w JSX, poprawione błędy kompilacji i wydajniejszy parser. Dla typowego projektu blogowego różnica jest niewidoczna, ale MDX 3 jest niezawodny w złożonych przypadkach z mieszanym Markdown/JSX.

Czy mogę używać komponentów Reacta, Vue i Svelte w jednym pliku MDX?

Tak — Astro obsługuje wiele frameworków jednocześnie. Dla komponentów interaktywnych w artykułach trzymaj się jednego frameworka: ułatwia utrzymanie, debugging i zarządzanie bundle'em.

Czy MDX wpływa na czas ładowania strony?

MDX kompiluje się do statycznego HTML w build time. Dla użytkownika końcowego nie ma różnicy względem Markdowna — chyba że osadzasz interaktywne komponenty. Wtedy koszt to bundle komponentu, nie samego MDX-a.

Jak zmigrować istniejące artykuły z Markdown do MDX?

Zmień rozszerzenie z .md na .mdx. Większość plików Markdown jest poprawnym MDX. Potencjalne konflikty: znaki < i { w treści mogą być interpretowane jako JSX. Po zmianie rozszerzeń przejdź po wszystkich plikach i uruchom astro build — błędy pojawią się natychmiast.

Czy MDX wspiera tabele i inne rozszerzenia GFM (GitHub Flavored Markdown)?

Tak, po włączeniu remark-gfm w konfiguracji Markdown/MDX. Wtedy działają tabele, listy kontrolnej, strikethrough i pozostałe rozszerzenia GitHub Flavored Markdown.

Kiedy komponent React w MDX wymaga client:only zamiast client:visible?

Gdy komponent w trakcie renderu sięga po API przeglądarki (window, document) albo używa biblioteki bez wsparcia SSR. Przy client:visible Astro renderuje go też na serwerze, co wywala build. client:only="react" pomija SSR i renderuje wyłącznie w przeglądarce — kosztem braku treści w HTML do czasu hydracji, więc nie używaj go dla treści ważnej dla SEO.

Jak ustawić własne komponenty dla nagłówków i linków we wszystkich plikach MDX naraz?

W Astro nie ma globalnego mapowania dla wszystkich plików MDX — obiekt components przekazujesz do <Content /> przy renderowaniu, a praktyczny wzorzec to zdefiniowanie mapy raz we wspólnym layoucie. W Next.js jest odwrotnie: globalną mapę wpisujesz raz do mdx-components.tsx i obowiązuje ona automatycznie we wszystkich plikach MDX, a mapowanie lokalne przekazane przez prop components scala się z globalnym.

Czym różni się MDX w Astro od MDX w Next.js?

Rdzeń (Markdown + JSX, importy komponentów, custom mapping) jest identyczny — różni się integracja. Astro: instalacja jedną komendą astro add mdx, natywny frontmatter, Content Collections z walidacją Zod i optymalizacja obrazów (astro:assets) z pudełka, interaktywność per użycie przez client:*. Next.js: @next/mdx z wymaganym plikiem mdx-components.tsx, brak natywnego frontmatteru (remark-frontmatter albo gray-matter), własna warstwa treści lub content-collections, next/image, interaktywność per komponent przez 'use client'. Globalne mapowanie komponentów jest wygodniejsze w Next.js, a szybki start z typowanym blogiem — w Astro.

Czy MDX w Next.js wymaga 'use client' dla interaktywnych komponentów?

Tak, jeśli komponent używa stanu, efektów albo API przeglądarki. W App Routerze wszystkie komponenty są domyślnie serwerowe (React Server Components), więc interaktywny widget oznaczasz dyrektywą 'use client' na górze jego pliku. To odwrotność modelu Astro, gdzie komponent jest statyczny, dopóki nie dodasz dyrektywy client:* w miejscu jego użycia w MDX.

O autorze

Maciej Sala

Maciej Sala — Product Manager i Frontend Developer z bogatym doświadczeniem w marketingu internetowym oraz SEO. Na co dzień pracuje z Reactem, Next.js i TypeScriptem, a ostatnio także z Astro i narzędziami do automatyzacji procesów AI. Sprawnie łączy perspektywę produktową z praktycznym podejściem do kodu. Przez kilka lat był związany z branżą gier wideo jako project manager i game designer. Absolwent historii na Uniwersytecie Jagiellońskim oraz studiów podyplomowych z marketingu internetowego na AGH w Krakowie. Po godzinach trenuje na siłowni, maluje figurki i rozwijam własne projekty.

Pomagam przekładać takie tematy na konkretne wdrożenia w frontendzie, SEO, analityce i procesie produktowym.

Skontaktuj się ze mną

Biblioteka wiedzy na temat Astro

Czytaj dalej

Zobacz więcej wpisów
Astro vs Next.js w 2026: Porównanie frameworków

Astro czy Next.js? Wybór frameworka musi być dokładnie przemyślany, zanim pojawi się pierwszy commit. Jeśli stoisz przed takim właśnie wyborem, w tym artykule staram się wykazać, w jakich obszarach najlepiej sprawdza się Astro , a w jakich będzie dominował Next.js .

Maciej Sala

Maciej Sala

Founder StriveLab

Astro Content Collections — typowany blog z walidacją Zod od podstaw

Brak walidacji frontmattera to prosta droga do błędów: literówki, brakujące opisy czy niespójne tagi stają się uciążliwym problemem, który odkryjemy dopiero na produkcji. Content Collections eliminują to ryzyko, wymuszając zgodność każdego pliku ze zdefiniowanym schematem, co zatrzymuje build, zanim błędne dane trafią na serwer.

Maciej Sala

Maciej Sala

Founder StriveLab

Migracja z WordPress na Astro: Jak zachować SEO? Przekierowania 301 i eksport treści

WordPress to CMS, z którym prosto zacząć, ale dość szybko pojawia się coraz więcej problemów. Wtyczki spowalniają stronę, a przy okazji bywają furtką dla włamań, Core Web Vitals wymagają głębokiej optymalizacji, a każda aktualizacja to potencjalne ryzyko regresji. Dobrze przeprowadzona migracja na Astro porządkuje te metryki i domyka większość luk — finalnie projekt staje się szybszy, bezpieczniejszy i przede wszystkim stabilniejszy.

Maciej Sala

Maciej Sala

Founder StriveLab