Kender du det?

Frustrationer i webudvikling

Messenger-kode

Frustration #4

Hvad kigger jeg på?

Frustration #18

Hvorfor virker det ikke?

Frustration #1

Har jeg rettet footer her?

Frustration #9

<!doctype html>
<html lang="da">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Forside</title>
  </head>
  <body>
    <!-- <SiteHeader /> -->
    <header>
      <a href="/">Dreamers</a>
      <nav>
        <a href="/">Home</a>
        <a href="/properties">Properties</a>
        <a href="/about">About</a>
        <a href="#testimonials">Testimonials</a>
        <a href="/blog">Blog</a>
      </nav>
      <a href="/contact">Contact us</a>
    </header>

    <main>
      <!-- <Hero /> -->
      <section>
        <h1>Find your best home to living dream</h1>
        <p>Unlock a seamless home-buying or investment experience.</p>
        <p>
          <a href="/contact">Contact us</a>
          <a href="/properties">Explore properties</a>
        </p>
        <img src="hero-house.jpg" alt="Modern house" />
      </section>

      <!-- <MissionBand /> -->
      <section>
        <p>Our Mission</p>
        <h2>Green Foundations A New Era for Community Real Estate</h2>
        <p>We go beyond transactions…</p>
      </section>

      <!-- <StatsRow /> -->
      <section>
        <ul>
          <li>
            <strong>1,200+</strong>
            <p>Properties Sold</p>
          </li>
          <li>
            <strong>95%</strong>
            <p>Customer Satisfaction</p>
          </li>
          <li>
            <strong>$500M+</strong>
            <p>In Transactions</p>
          </li>
        </ul>
      </section>

      <!-- <ListingsSection /> -->
      <section>
        <h2>Unlock Your Ideal Living Space</h2>

        <nav>
          <button type="button">All Properties</button>
          <button type="button">Family House</button>
          <button type="button">Villa</button>
          <button type="button">Apartment</button>
          <button type="button">Mansion</button>
          <button type="button">Green House</button>
        </nav>

        <ul>
          <li>
            <img src="p1.jpg" alt="Silver Birch Villa" />
            <h3>Silver Birch Villa</h3>
            <p>Birmingham, UK</p>
            <p>$850,000</p>
          </li>
          <li>
            <img src="p2.jpg" alt="Maple Grove Cottage" />
            <h3>Maple Grove Cottage</h3>
            <p>Liverpool, UK</p>
            <p>$500,000</p>
          </li>
          <li>
            <img src="p3.jpg" alt="Cedar Hill Estate" />
            <h3>Cedar Hill Estate</h3>
            <p>Edinburgh, UK</p>
            <p>$1,200,000</p>
          </li>
        </ul>
      </section>

      <!-- <ValuePropsSection /> -->
      <section>
        <h2>Seamless for Simplicity Built Trusted Results</h2>

        <ul>
          <li>
            <strong>35K</strong>
            <p>Happy clients</p>
          </li>
          <li>
            <strong>120+</strong>
            <p>Partners</p>
          </li>
          <li>
            <strong>97%</strong>
            <p>Satisfaction</p>
          </li>
        </ul>

        <img src="v1.jpg" alt="Building detail" />
        <img src="v2.jpg" alt="Architecture" />
      </section>

      <!-- <TrendingSection /> -->
      <section>
        <h2>Top Trending Dreams</h2>
        <ul>
          <li>
            <img src="t1.jpg" alt="Pine Valley Retreat" />
            <p>Pine Valley Retreat</p>
          </li>
          <li>
            <img src="t2.jpg" alt="Elm Street Apartment" />
            <p>Elm Street Apartment</p>
          </li>
          <li>
            <img src="t3.jpg" alt="Willow Creek Lodge" />
            <p>Willow Creek Lodge</p>
          </li>
          <li>
            <img src="t4.jpg" alt="Hillside Escape" />
            <p>Hillside Escape</p>
          </li>
        </ul>
      </section>

      <!-- <TestimonialsSection /> -->
      <section id="testimonials">
        <h2>Real Stories, Real Success with Fintech.</h2>
        <ul>
          <li>
            <p>They stay in place and deliver amazing value.</p>
            <p>Martin John — Homeowner</p>
          </li>
          <li>
            <p>The process was smooth and transparent.</p>
            <p>Malika James — Contractor</p>
          </li>
          <li>
            <p>Reliable results and good guidance.</p>
            <p>Theseer Omas — Investor</p>
          </li>
        </ul>
      </section>

      <!-- <ContactCTA /> -->
      <section>
        <h2>Get In Touch</h2>
        <a href="/contact">Get Started for Free</a>
      </section>
    </main>

    <!-- <SiteFooter /> -->
    <footer>
      <p>Dreamers</p>

      <h3>Our Links</h3>
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/services">Services</a></li>
      </ul>

      <h3>Our Condition</h3>
      <ul>
        <li><a href="/privacy">Privacy Policy</a></li>
        <li><a href="/terms">Terms</a></li>
      </ul>

      <h3>Follow Us</h3>
      <ul>
        <li><a href="https://x.com">X</a></li>
        <li><a href="https://instagram.com">Instagram</a></li>
        <li><a href="https://facebook.com">Facebook</a></li>
      </ul>

      <p>© 2026</p>
    </footer>
  </body>
</html>

Hvor er nu sektionen?

Frustration #16

<!doctype html>
<html lang="da">
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <title>Forside</title>
  </head>
  <body>
    <!-- <SiteHeader /> -->
    <header>
      <a href="/">Dreamers</a>
      <nav>
        <a href="/">Home</a>
        <a href="/properties">Properties</a>
        <a href="/about">About</a>
        <a href="#testimonials">Testimonials</a>
        <a href="/blog">Blog</a>
      </nav>
      <a href="/contact">Contact us</a>
    </header>

    <main>
      <!-- <Hero /> -->
      <section>
        <h1>Find your best home to living dream</h1>
        <p>Unlock a seamless home-buying or investment experience.</p>
        <p>
          <a href="/contact">Contact us</a>
          <a href="/properties">Explore properties</a>
        </p>
        <img src="hero-house.jpg" alt="Modern house" />
      </section>

      <!-- <MissionBand /> -->
      <section>
        <p>Our Mission</p>
        <h2>Green Foundations A New Era for Community Real Estate</h2>
        <p>We go beyond transactions…</p>
      </section>

      <!-- <StatsRow /> -->
      <section>
        <ul>
          <li>
            <strong>1,200+</strong>
            <p>Properties Sold</p>
          </li>
          <li>
            <strong>95%</strong>
            <p>Customer Satisfaction</p>
          </li>
          <li>
            <strong>$500M+</strong>
            <p>In Transactions</p>
          </li>
        </ul>
      </section>

      <!-- <ListingsSection /> -->
      <section>
        <h2>Unlock Your Ideal Living Space</h2>

        <nav>
          <button type="button">All Properties</button>
          <button type="button">Family House</button>
          <button type="button">Villa</button>
          <button type="button">Apartment</button>
          <button type="button">Mansion</button>
          <button type="button">Green House</button>
        </nav>

        <ul>
          <li>
            <img src="p1.jpg" alt="Silver Birch Villa" />
            <h3>Silver Birch Villa</h3>
            <p>Birmingham, UK</p>
            <p>$850,000</p>
          </li>
          <li>
            <img src="p2.jpg" alt="Maple Grove Cottage" />
            <h3>Maple Grove Cottage</h3>
            <p>Liverpool, UK</p>
            <p>$500,000</p>
          </li>
          <li>
            <img src="p3.jpg" alt="Cedar Hill Estate" />
            <h3>Cedar Hill Estate</h3>
            <p>Edinburgh, UK</p>
            <p>$1,200,000</p>
          </li>
        </ul>
      </section>

      <!-- <ValuePropsSection /> -->
      <section>
        <h2>Seamless for Simplicity Built Trusted Results</h2>

        <ul>
          <li>
            <strong>35K</strong>
            <p>Happy clients</p>
          </li>
          <li>
            <strong>120+</strong>
            <p>Partners</p>
          </li>
          <li>
            <strong>97%</strong>
            <p>Satisfaction</p>
          </li>
        </ul>

        <img src="v1.jpg" alt="Building detail" />
        <img src="v2.jpg" alt="Architecture" />
      </section>

      <!-- <TrendingSection /> -->
      <section>
        <h2>Top Trending Dreams</h2>
        <ul>
          <li>
            <img src="t1.jpg" alt="Pine Valley Retreat" />
            <p>Pine Valley Retreat</p>
          </li>
          <li>
            <img src="t2.jpg" alt="Elm Street Apartment" />
            <p>Elm Street Apartment</p>
          </li>
          <li>
            <img src="t3.jpg" alt="Willow Creek Lodge" />
            <p>Willow Creek Lodge</p>
          </li>
          <li>
            <img src="t4.jpg" alt="Hillside Escape" />
            <p>Hillside Escape</p>
          </li>
        </ul>
      </section>

      <!-- <TestimonialsSection /> -->
      <section id="testimonials">
        <h2>Real Stories, Real Success with Fintech.</h2>
        <ul>
          <li>
            <p>They stay in place and deliver amazing value.</p>
            <p>Martin John — Homeowner</p>
          </li>
          <li>
            <p>The process was smooth and transparent.</p>
            <p>Malika James — Contractor</p>
          </li>
          <li>
            <p>Reliable results and good guidance.</p>
            <p>Theseer Omas — Investor</p>
          </li>
        </ul>
      </section>

      <!-- <ContactCTA /> -->
      <section>
        <h2>Get In Touch</h2>
        <a href="/contact">Get Started for Free</a>
      </section>
    </main>

    <!-- <SiteFooter /> -->
    <footer>
      <p>Dreamers</p>

      <h3>Our Links</h3>
      <ul>
        <li><a href="/">Home</a></li>
        <li><a href="/services">Services</a></li>
      </ul>

      <h3>Our Condition</h3>
      <ul>
        <li><a href="/privacy">Privacy Policy</a></li>
        <li><a href="/terms">Terms</a></li>
      </ul>

      <h3>Follow Us</h3>
      <ul>
        <li><a href="https://x.com">X</a></li>
        <li><a href="https://instagram.com">Instagram</a></li>
        <li><a href="https://facebook.com">Facebook</a></li>
      </ul>

      <p>© 2026</p>
    </footer>
  </body>
</html>
ValuePropsSection

?

Hvad nu hvis?

Hvad nu hvis?

<MainLayout>

  <Hero />
  <MissionBand />
  <StatsRow />
  <ListingsSection />
  <ValuePropsSection />
  <TrendingSection />
  <TestimonialsSection />
  <ContactCTA />

</MainLayout>
ValuePropsSection

Hvad nu hvis?

<MainLayout>

  <Hero />
  <MissionBand />
  <StatsRow />
  <ListingsSection />
  <ValuePropsSection />
  <TrendingSection />
  <TestimonialsSection />
  <ContactCTA />

</MainLayout>
ValuePropsSection
<section>
  <h2>Seamless for Simplicity Built Trusted Results</h2>

  <ul>
    <li>
      <strong>35K</strong>
      <p>Happy clients</p>
    </li>
    <li>
      <strong>120+</strong>
      <p>Partners</p>
    </li>
    <li>
      <strong>97%</strong>
      <p>Satisfaction</p>
    </li>
  </ul>

  <img src="v1.jpg" alt="Building detail" />
  <img src="v2.jpg" alt="Architecture" />
</section>
ValuePropsSection
<MainLayout>

  <Hero />
  <MissionBand />
  <StatsRow />
  <ListingsSection />
  <ValuePropsSection />
  <TrendingSection />
  <TestimonialsSection />
  <ContactCTA />

</MainLayout>
.astro
<section>
  <h2>Seamless for Simplicity Built Trusted Results</h2>

  <ul>
    <li>
      <strong>35K</strong>
      <p>Happy clients</p>
    </li>
    <li>
      <strong>120+</strong>
      <p>Partners</p>
    </li>
    <li>
      <strong>97%</strong>
      <p>Satisfaction</p>
    </li>
  </ul>

  <img src="v1.jpg" alt="Building detail" />
  <img src="v2.jpg" alt="Architecture" />
</section>
ValuePropsSection
<MainLayout>

  <Hero />
  <MissionBand />
  <StatsRow />
  <ListingsSection />
  <ValuePropsSection />
  <TrendingSection />
  <TestimonialsSection />
  <ContactCTA />

</MainLayout>
.astro

Recap and beyond

Målet for i dag

  1. forstå, hvad Astro er – og hvad det ikke er

  1. forstå, hvilke problemer Astro forsøger at fjerne

  1. forstå, hvad en komponent er

forstå, hvorfor Astro kræver et build-/servermiljø

Recap and beyond

Målet for i dag

Viden om

Færdigheder

  1. forstå, hvad Astro er – og hvad det ikke er

  1. forstå, hvilke problemer Astro forsøger at fjerne

  1. forstå, hvad en komponent er

forstå, hvorfor Astro kræver et build-/servermiljø

  1. kunne identificere gentagelser i et UI (komponenter)

  1. kunne opbygge en side af komponenter (ikke copy-paste)

  1. kunne styre simple variationer med props

  1. kunne style komponenter lokalt (scoped styles)

Recap and beyond

Målet for i dag

Viden om

  1. forstå, hvad Astro er – og hvad det ikke er

  1. forstå, hvilke problemer Astro forsøger at fjerne

  1. forstå, hvad en komponent er

forstå, hvorfor Astro kræver et build-/servermiljø

Færdigheder

  1. kunne identificere gentagelser i et UI (komponenter)

  1. kunne opbygge en side af komponenter (ikke copy-paste)

  1. kunne styre simple variationer med props

  1. kunne style komponenter lokalt (scoped styles)

D

eveloper E   perience

x

D

eveloper E   perience

x

Developer Experience

Hvordan det føles at bygge noget

Astro

Astro

Et framework, der bl.a. handler om DX

Framework

Et værktøj, der hjælper med at bygge hurtigere og smartere

(... men ikke flottere...)

Hvorfor lige Astro?

  • Det er let at komme i gang med
  • Forholdsvis lille læringskurve
  • Det er bare HTML & CSS...

Marketing-afdelingen

Hvad hjælper Astro med?

  • Struktur og overblik
  • Genbrug af dele i stedet for copy-paste
  • Styling uden konflikter
  • Diverse optimeringer

Astro løser ikke ét stort problem, men fjerner mange små irritationer, du allerede har accepteret som “sådan er webudvikling”.

Komponenter

Genbrug af dele i stedet for copy-paste

Komponenter

Genbrug af dele i stedet for copy-paste

Hvornår copy-paster I kode?

Hvornår er noget en komponent?

  • En genbrugelig skabelon, der kan modtage data
  • Hvis noget html skal copy-pastes, så er det nok en component
  • Hvis du kan give det et navn (a la footer) så er det nok en component

Alt kan være en komponent, men gode komponenter handler om overblik og klarhed; gør koden lettere at læse.

gruppe-øvelse

Identificer komponenter

Kan du og din sidemakker få øje på komponenter?

  • Hvilke dele gentager sig, hvis der var 10 indlæg? (hvad ville du kopiere?)
     
  • Hvilke dele kunne få deres eget navn?

Top navigation (logo + actions)

Stories bar (Story items)

Feed

Post card

- header, media, actions

- likes, caption, comments mm.

Avatar

Icon

Icon Button

Komponenter

Verified Badge

- timestamp

Komponenter

timestamp

<time datetime={datetime}>
  {label}
</time>

Fra HTML til Astro

<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <header>
      <nav>
        <ul>
          <li><a href="#">Forside</a></li>
          <li><a href="#">Om</a></li>
          <li><a href="#">Kontact</a></li>
        </ul>
      </nav>
    </header>

    <main>
      <section id="hero">
        <h2>Dette er et Hero-Image</h2>
        <p>Her er noget introduktionstekst om denne side.</p>
        <a href="#0">Lær Mere</a>
      </section>

      <section id="services">
        <h2>Vores Services</h2>

        <div class="service">
          <h3>Service 1</h3>
          <p>Beskrivelse af service 1.</p>
        </div>

        <div class="service">
          <h3>Service 2</h3>
          <p>Beskrivelse af service 2.</p>
        </div>

        <div class="service">
          <h3>Service 3</h3>
          <p>Beskrivelse af service 3.</p>
        </div>
      </section>
    </main>

    <footer>
      <p>© 2026 Min Side. Alle rettigheder forbeholdes.</p>
    </footer>

  </body>
</html>
<header>
  <nav>
    <ul>
      <li><a href="#">Forside</a></li>
      <li><a href="#">Om</a></li>
      <li><a href="#">Kontact</a></li>
    </ul>
  </nav>
</header>
<header>
  <nav>
    <ul>
      <li><a href="#">Forside</a></li>
      <li><a href="#">Om</a></li>
      <li><a href="#">Kontact</a></li>
    </ul>
  </nav>
</header>

<main>
  <section id="hero">
    <h2>Dette er et Hero-Image</h2>
    <p>Her er noget introduktionstekst om denne side.</p>
    <a href="#0">Lær Mere</a>
  </section>

  <section id="services">
    <h2>Vores Services</h2>

    <div class="service">
      <h3>Service 1</h3>
      <p>Beskrivelse af service 1.</p>
    </div>

    <div class="service">
      <h3>Service 2</h3>
      <p>Beskrivelse af service 2.</p>
    </div>

    <div class="service">
      <h3>Service 3</h3>
      <p>Beskrivelse af service 3.</p>
    </div>
  </section>
</main>

<footer>
  <p>© 2026 Min Side. Alle rettigheder forbeholdes.</p>
</footer>
<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>
<div class="service">
  <h3>Service 1</h3>
  <p>Beskrivelse af service 1.</p>
</div>
<section id="services">
  <h2>Vores Services</h2>
  <Service />
  <Service />
  <Service />
</section>

Fra HTML til Astro

Fra HTML til Astro

<header>
  <nav>
    <ul>
      <li><a href="#">Forside</a></li>
      <li><a href="#">Om</a></li>
      <li><a href="#">Kontact</a></li>
    </ul>
  </nav>
</header>
<header>
  <nav>
    <ul>
      <li><a href="#">Forside</a></li>
      <li><a href="#">Om</a></li>
      <li><a href="#">Kontact</a></li>
    </ul>
  </nav>
</header>

<main>
  <section id="hero">
    <h2>Dette er et Hero-Image</h2>
    <p>Her er noget introduktionstekst om denne side.</p>
    <a href="#0">Lær Mere</a>
  </section>

  <section id="services">
    <h2>Vores Services</h2>

    <div class="service">
      <h3>Service 1</h3>
      <p>Beskrivelse af service 1.</p>
    </div>

    <div class="service">
      <h3>Service 2</h3>
      <p>Beskrivelse af service 2.</p>
    </div>

    <div class="service">
      <h3>Service 3</h3>
      <p>Beskrivelse af service 3.</p>
    </div>
  </section>
</main>

<footer>
  <p>© 2026 Min Side. Alle rettigheder forbeholdes.</p>
</footer>
<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>
<div class="service">
  <h3>Service 1</h3>
  <p>Beskrivelse af service 1.</p>
</div>
<section id="services">
  <h2>Vores Services</h2>
  <ServiceCard />
  <ServiceCard />
  <ServiceCard />
</section>
<header>
  <h1>Velkommen til Min Side</h1>
  <nav>
    <ul>
      <li><a href="#">Home</a></li>
      <li><a href="#">About</a></li>
      <li><a href="#">Contact</a></li>
    </ul>
  </nav>
</header>
<section id="hero">
  <h2>Dette er et Hero-Image</h2>
  <p>Her er noget introduktionstekst om denne side.</p>
  <button>Lær Mere</button>
</section>
<div class="service">
  <h3>Service 1</h3>
  <p>Beskrivelse af service 1.</p>
</div>
<section id="services">
  <h2>Vores Services</h2>
  <Service />
  <Service />
  <Service />
</section>
<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <Header />
    <Hero />
  	<Services />
    <Footer />

  </body>
</html>

Fra HTML til Astro

<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <Header />
    <Hero />
  	<Services />
    <Footer />

  </body>
</html>

Fra HTML til Astro

<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <header>
      <nav>
        <ul>
          <li><a href="#">Forside</a></li>
          <li><a href="#">Om</a></li>
          <li><a href="#">Kontact</a></li>
        </ul>
      </nav>
    </header>

    <main>
      <section id="hero">
        <h2>Dette er et Hero-Image</h2>
        <p>Her er noget introduktionstekst om denne side.</p>
        <a href="#0">Lær Mere</a>
      </section>

      <section id="services">
        <h2>Vores Services</h2>

        <div class="service">
          <h3>Service 1</h3>
          <p>Beskrivelse af service 1.</p>
        </div>

        <div class="service">
          <h3>Service 2</h3>
          <p>Beskrivelse af service 2.</p>
        </div>

        <div class="service">
          <h3>Service 3</h3>
          <p>Beskrivelse af service 3.</p>
        </div>
      </section>
    </main>

    <footer>
      <p>© 2026 Min Side. Alle rettigheder forbeholdes.</p>
    </footer>

  </body>
</html>
<MainLayout>
  <Hero />
  <Services />
</MainLayout>
<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <Header />
    <Hero />
  	<Services />
    <Footer />

  </body>
</html>

Fra HTML til Astro

Demo

Lad os prøve det...

---
import Header from "../components/Header.astro";
import Hero from "../components/Hero.astro";
import ServiceList from "../components/ServiceList.astro";
import Footer from "../components/Footer.astro";
---
<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <Header />
    <main>
      <Hero />
      <ServiceList />
    </main>
    <Footer />

  </body>
</html>

VS Code

Når vi arbejder i Astro…

 browseren forstår ikke "import", "<Header />" mm.,
 koden kører ikke direkte i browseren.
 “Live server” virker ikke her.
 koden skal samles og oversættes først.

Derfor har vi installeret Node

Udviklingsmiljø, der kan:
 forstå Astro-filer
 samle komponenter til HTML
 starte en lokal server
 opdatere siden automatisk, når vi gemmer

---
import Header from "../components/Header.astro";
import Hero from "../components/Hero.astro";
import ServiceList from "../components/ServiceList.astro";
import Footer from "../components/Footer.astro";
---
<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <Header />
    <main>
      <Hero />
      <ServiceList />
    </main>
    <Footer />

  </body>
</html>

Når vi arbejder i Astro…

 browseren forstår ikke "import", "<Header />" mm.,
 koden kører ikke direkte i browseren.
 “Live server” er ikke nok,
 koden skal samles og oversættes først

Derfor har vi installeret Node

Udviklingsmiljø, der kan:
 forstå Astro-filer
 samle komponenter til HTML
 starte en lokal server
 opdatere siden automatisk, når vi gemmer

Det er bare et program på computeren,
der kan køre JavaScript uden for browseren.
Astro bruger det til at bygge hjemmesiden,
før browseren ser den.

VS Code

---
import Header from "../components/Header.astro";
import Hero from "../components/Hero.astro";
import ServiceList from "../components/ServiceList.astro";
import Footer from "../components/Footer.astro";
---
<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <Header />
    <main>
      <Hero />
      <ServiceList />
    </main>
    <Footer />

  </body>
</html>
<!doctype html>
<html lang="da">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width" />
    <title>Hjem</title>
  </head>
  <body>

    <header>
      <nav>
        <ul>
          <li><a href="#">Forside</a></li>
          <li><a href="#">Om</a></li>
          <li><a href="#">Kontact</a></li>
        </ul>
      </nav>
    </header>

    <main>
      <section id="hero">
        <h2>Dette er et Hero-Image</h2>
        <p>Her er noget introduktionstekst om denne side.</p>
        <a href="#0">Lær Mere</a>
      </section>

      <section id="services">
        <h2>Vores Services</h2>

        <div class="service">
          <h3>Service 1</h3>
          <p>Beskrivelse af service 1.</p>
        </div>

        <div class="service">
          <h3>Service 2</h3>
          <p>Beskrivelse af service 2.</p>
        </div>

        <div class="service">
          <h3>Service 3</h3>
          <p>Beskrivelse af service 3.</p>
        </div>
      </section>
    </main>

    <footer>
      <p>© 2026 Min Side. Alle rettigheder forbeholdes.</p>
    </footer>

  </body>
</html>

Browser

->

VS Code

Identificer

Header.astro

Button.astro

Footer.astro

Card.astro

CardSection.astro

Hero.astro

Components

Følg med nu...

Om lidt er det din tur

Opbygning

Komponenter

---

---

<article>
  <h2></h2>
  <p></p>
</article>

<style>
  article {...}
</style>

"Single file component", som betyder, at vi samler al relevant HTML, CSS (og JavaScript) i den enkelte component

---

---

<article>
  <h2></h2>
  <p></p>
</article>

<style>
  article {...}
</style>

<script>
  ...
</script>

"Single file component", som betyder, at vi samler al relevant HTML, CSS (og JavaScript) i den enkelte component

Opbygning

Komponenter

Fences

---

---

"Frontmatter"

import "../styles/global.css"

Komponenter

---

---
import "../styles/global.css"
import Component from "../components/Component.astro"

Importer stylesheet

Fences

Komponenter

---

---
import "../styles/global.css"
import Component from "../components/Component.astro"
const { prop } = Astro.props;

Importer component

Fences

Komponenter

---

---
import "../styles/global.css"
import Component from "../components/Component.astro"
const { prop } = Astro.props;

Saml props op

const now = new Date();
const localTime = now.toLocaleTimeString("da-DK");

Fences

Komponenter

---


---
import "../styles/global.css"
const { prop } = Astro.props;

JavaScript på serveren ("build time")

const now = new Date();
const localTime = now.toLocaleTimeString("da-DK");

Fences

Komponenter

---


---

<p>Hej, klokken er {localTime}</p>

JavaScript på serveren ("build time")

const now = new Date();
const localTime = now.toLocaleTimeString("da-DK");

Hvad var klokken, der jeg byggede siden (statisk)

Fences

Komponenter

HTML-delen

Template

---


---

<p>Hej, klokken er {localTime}</p>

Komponenter

{} bruges til at vise props i HTML

Props

---

---
<article>
  <h2>{title}</h2>
  <p>{body}</p>
</article>

Komponenter

Saml props op

Props

---
const { title, body } = Astro.props;
---
<article>
  <h2>{title}</h2>
  <p>{body}</p>
</article>

Komponenter

Scoped styles

Styles

<article>
  <h2>{title}</h2>
  <p>{body}</p>
</article>

<style>
  article {
    background: #bada55;
  }
  
  h2 {
    color: #5000ca;
  }
</style>

Komponenter

Rammer kun <h2> i komponent

Overblik

Komponenter

├── src/
    └── components/
    	└── Header.astro
    	└── Hero.astro
    	└── 
    	└── ServiceList.astro
    	└── Footer.astro
ServiceCard.astro
---
const { title, description } = Astro.props;
---
<div class="service">
  <h3>{title}</h3>
  <p>{description}</p>
</div>
ServiceCard.astro

Fil

Komponenter

---
import ServiceCard from "../components/                 ";
---

<ServiceCard />
<ServiceCard />
<ServiceCard />
ServiceCard.astro

Konvention: Samme navn

Komponenter

Import

Props

Hvert card har nu forskelligt indhold

Komponenter

---
import ServiceCard from "../components/                 ";
---

<ServiceCard
  title="Service 1"
  description="Beskrivelse af service 1." />
<ServiceCard
  title="Service 2"
  description="Beskrivelse af service 2." />
ServiceCard.astro

Prop =
selvopfunden attribut

---
import ServiceCard from "../components/                 ";
---

<ServiceCard
  title="Service 1"
  description="Beskrivelse af service 1."
/>
ServiceCard.astro
---
const { title, description } = Astro.props;
---
<div class="service">
  <h3>{title}</h3>
  <p>{description}</p>
</div>

Opvarmningsøvelser

øvelse

<slot />

Slots

<Box>Get started</Box>
<div class="box">
  <slot />
</div>
Get started

Slots

<Box>Get started</Box>
<div class="box">
  <slot />
</div>
Get started

Slot er et hul, hvor markup indsættes.

Slots

<Card>
  <p>Lorem ipsum...</p>
</Card>

Slots

Props

vs.

<Card description="Lorem ipsum..." />

Hvis komponenten skal kende strukturen

Hvis indholdets struktur varierer

<InfoBox>
  <p>Dette er vigtig information.</p>
  <p>Læs det grundigt.</p>
</InfoBox>

Hvornår giver slots mening?

Indholdets struktur kan variere

<FAQItem question="Hvad er Astro?">
  <p>Astro er et web-framework.</p>
</FAQItem>

Indholdets struktur kan variere

Fast struktur - skal være der

Hvornår giver slots mening?

<FAQItem question="Hvad er Astro?">
  <p>Astro er et web-framework.</p>
</FAQItem>

Indholdets struktur kan variere

---
const { question } = Astro.props;
---

<h3>{question}</h3>
<div>
  <slot />
</div>

Fast struktur - skal være der

Hvornår giver slots mening?

<FAQItem question="Hvad er Astro?">
  <p>Astro er et web-framework.</p>
</FAQItem>

Scoped styles virker ikke med slots

<h3>{question}</h3>
<div>
  <slot /> <!-- ????? -->
</div>

<style>
  p {
    color: red; /* ????? */
  }
</style>

OBS!

<ButtonLink>Se mere</ButtonLink>

Hvor giver det mening lige nu?

Ingen ekstra markup, bare tekst

Wrappers

<Section title="">
  <Card title="" img="" />
  <Card title="" img="" />
</Section>

Hvor giver det mening lige nu?

Komponenter styrer selv deres styling

Wrappers

---
const { title } = Astro.props;
---

<section class="section">
  <h2 class="section__title">{title}</h2>
  <div class="section__content">
    <slot />
  </div>
</section>

Hvor giver det mening lige nu?

Wrappers

<Section title="">
  <Card title="" img="" />
  <Card title="" img="" />
</Section>

Card er slotted indhold

<section class="section">
  <h2 class="section__title">{title}</h2>
  <div class="section__content">
    <slot />
  </div>
</section>

<style>
  .section__content {
    display: grid;
    grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  }
</style>

Hvor giver det mening lige nu?

<Section> styrer layout af indhold (slot)

Vi kigger videre på det i morgen...

  • Variants
  • Conditional rendering
  • Layout-komponenter
  • Pages

Tema 7: Introduktion til Astro

By Dannie Vinther

Tema 7: Introduktion til Astro

Tema 7: Astro

  • 70