The Bottom Line

Footers contain secondary navigation, legal links, contact info, and copyright notices. Like headers, they belong in the layout so they appear consistently across all pages.


What You’ll Learn

  • Add a footer below the page content
  • Include common footer elements
  • Complete the basic layout structure

Update your layout to include a footer after <main>:

<!-- filename: src/routes/+layout.svelte -->
<script>
  let { children } = $props();
</script>

<div class="app">
  <header>
    <nav>
      <a href="/" class="logo">BookIt</a>
      
      <ul>
        <li><a href="/services">Services</a></li>
        <li><a href="/about">About</a></li>
        <li><a href="/contact">Contact</a></li>
      </ul>
    </nav>
  </header>
  
  <main>
    {@render children()}
  </main>
  
  <footer>
    <div class="footer-content">
      <div class="footer-section">
        <h4>BookIt</h4>
        <p>Simple online booking for local services.</p>
      </div>
      
      <div class="footer-section">
        <h4>Quick Links</h4>
        <ul>
          <li><a href="/services">Services</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </div>
      
      <div class="footer-section">
        <h4>Contact</h4>
        <p>hello@bookit.example</p>
        <p>(555) 123-4567</p>
      </div>
    </div>
    
    <div class="footer-bottom">
      <p>&copy; {new Date().getFullYear()} BookIt. All rights reserved.</p>
    </div>
  </footer>
</div>

The footer includes:

  • Brand description
  • Quick navigation links
  • Contact information
  • Copyright with dynamic year

Add footer styles to your existing <style> block:

<style>
  /* ... existing header/nav/main styles ... */
  
  footer {
    background: #333;
    color: #fff;
    padding: 2rem 1rem 1rem;
    margin-top: auto;
  }
  
  .footer-content {
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
    max-width: 1200px;
    margin: 0 auto;
  }
  
  .footer-section {
    flex: 1;
    min-width: 200px;
  }
  
  .footer-section h4 {
    margin: 0 0 1rem 0;
    font-size: 1rem;
  }
  
  .footer-section p {
    margin: 0.5rem 0;
    color: #aaa;
  }
  
  .footer-section ul {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  
  .footer-section li {
    margin: 0.5rem 0;
  }
  
  .footer-section a {
    color: #aaa;
    text-decoration: none;
  }
  
  .footer-section a:hover {
    color: #fff;
  }
  
  .footer-bottom {
    border-top: 1px solid #444;
    margin-top: 2rem;
    padding-top: 1rem;
    text-align: center;
    max-width: 1200px;
    margin-left: auto;
    margin-right: auto;
  }
  
  .footer-bottom p {
    margin: 0;
    color: #888;
    font-size: 0.875rem;
  }
</style>

Notice this line:

<p>&copy; {new Date().getFullYear()} BookIt. All rights reserved.</p>

The {new Date().getFullYear()} expression runs JavaScript to get the current year. When 2025 becomes 2026, the footer automatically updates. No manual changes needed.


Test the Complete Layout

Visit any page. You should see:

  1. Header — Logo and navigation at top
  2. Main — Page-specific content in the middle
  3. Footer — Site info and links at bottom

Scroll to the bottom of short pages — the footer should be at the bottom of the viewport (thanks to margin-top: auto on footer and flexbox on .app).


The Complete Layout

Here’s the full +layout.svelte:

<!-- filename: src/routes/+layout.svelte -->
<script>
  let { children } = $props();
</script>

<div class="app">
  <header>
    <nav>
      <a href="/" class="logo">BookIt</a>
      
      <ul>
        <li><a href="/services">Services</a></li>
        <li><a href="/about">About</a></li>
        <li><a href="/contact">Contact</a></li>
      </ul>
    </nav>
  </header>
  
  <main>
    {@render children()}
  </main>
  
  <footer>
    <div class="footer-content">
      <div class="footer-section">
        <h4>BookIt</h4>
        <p>Simple online booking for local services.</p>
      </div>
      
      <div class="footer-section">
        <h4>Quick Links</h4>
        <ul>
          <li><a href="/services">Services</a></li>
          <li><a href="/about">About</a></li>
          <li><a href="/contact">Contact</a></li>
        </ul>
      </div>
      
      <div class="footer-section">
        <h4>Contact</h4>
        <p>hello@bookit.example</p>
        <p>(555) 123-4567</p>
      </div>
    </div>
    
    <div class="footer-bottom">
      <p>&copy; {new Date().getFullYear()} BookIt. All rights reserved.</p>
    </div>
  </footer>
</div>

<style>
  .app {
    min-height: 100vh;
    display: flex;
    flex-direction: column;
  }
  
  header {
    background: #f8f9fa;
    border-bottom: 1px solid #e9ecef;
    padding: 1rem;
  }
  
  nav {
    display: flex;
    justify-content: space-between;
    align-items: center;
    max-width: 1200px;
    margin: 0 auto;
  }
  
  .logo {
    font-size: 1.5rem;
    font-weight: bold;
    text-decoration: none;
    color: #333;
  }
  
  header ul {
    display: flex;
    gap: 1.5rem;
    list-style: none;
    margin: 0;
    padding: 0;
  }
  
  header li a {
    text-decoration: none;
    color: #666;
  }
  
  header li a:hover {
    color: #333;
  }
  
  main {
    flex: 1;
    padding: 2rem;
    max-width: 1200px;
    margin: 0 auto;
    width: 100%;
  }
  
  footer {
    background: #333;
    color: #fff;
    padding: 2rem 1rem 1rem;
    margin-top: auto;
  }
  
  .footer-content {
    display: flex;
    flex-wrap: wrap;
    gap: 2rem;
    max-width: 1200px;
    margin: 0 auto;
  }
  
  .footer-section {
    flex: 1;
    min-width: 200px;
  }
  
  .footer-section h4 {
    margin: 0 0 1rem 0;
    font-size: 1rem;
  }
  
  .footer-section p {
    margin: 0.5rem 0;
    color: #aaa;
  }
  
  .footer-section ul {
    list-style: none;
    padding: 0;
    margin: 0;
  }
  
  .footer-section li {
    margin: 0.5rem 0;
  }
  
  .footer-section a {
    color: #aaa;
    text-decoration: none;
  }
  
  .footer-section a:hover {
    color: #fff;
  }
  
  .footer-bottom {
    border-top: 1px solid #444;
    margin-top: 2rem;
    padding-top: 1rem;
    text-align: center;
    max-width: 1200px;
    margin-left: auto;
    margin-right: auto;
  }
  
  .footer-bottom p {
    margin: 0;
    color: #888;
    font-size: 0.875rem;
  }
</style>

Common Mistakes

<!-- ❌ Footer appears above page content -->
<footer>...</footer>
{@render children()}

<!-- ✅ Footer appears below page content -->
{@render children()}
<footer>...</footer>

Order matters. Content renders in the order it appears in your layout.

Hardcoding the Year

<!-- ❌ Needs manual update every year -->
<p>&copy; 2025 BookIt</p>

<!-- ✅ Always current -->
<p>&copy; {new Date().getFullYear()} BookIt</p>

Dynamic year means one less thing to maintain.


Summary

BookIt now has a complete layout with header and footer. Every page automatically gets consistent navigation and site information without any page-level code.

Key takeaways:

  • Footer goes after {@render children()} in the layout
  • Use semantic <footer> element for accessibility
  • Dynamic expressions like {new Date().getFullYear()} keep content current

Next Steps

The root layout wraps everything, but sometimes sections need additional wrapping. Continue with Nested Layouts to learn how the services section can have its own sub-navigation.