Footer

apps/www/src/components/Footer.astro · 81 lines · group Layout & internals

default locale lives at the site root; other locales are prefixed

Used by

Rendered by the layout on every page of every www site.

Props

NameTypeRequiredDefaultDescription
localestringyes

Source apps/www/src/components/Footer.astro @ gitt.one

---
import pagesConfig from '../../pages.config.js';
import { localePrefix, perLocale } from '../lib/locales';

interface Props {
  locale: string;
}

const { locale } = Astro.props;
// default locale lives at the site root; other locales are prefixed
const prefix = localePrefix(locale);

// same menu as the header, minus the home entry (pages.config.js, per
// locale when given as a map — README §4.13);
// anchors ('#contacts') link to the home page without a trailing slash
const footerNavigation = perLocale<{ name: string; path: string }[]>(pagesConfig.navigation, locale, [])
  .filter(({ path }: { path: string }) => path)
  .map(({ name, path }: { name: string; path: string }) => ({
    name,
    href: path.startsWith('#') ? `${prefix}${path}` : `${prefix}${path}/`,
  }));

// legal requisites and similar footer lines come from the site config
const footerLines = perLocale<string[]>(pagesConfig.footerLines, locale, []);

const year = new Date().getFullYear();
---

<footer class="relative mt-24 bg-gray-900 sm:mt-12">
  <div
    class="mx-auto max-w-md overflow-hidden px-4 py-12 sm:max-w-3xl sm:px-6 lg:max-w-7xl lg:px-8"
  >
    <nav class="-mx-5 -my-2 flex flex-wrap justify-center" aria-label="Footer">
      {
        footerNavigation.map((item) => (
          <div class="px-5 py-2">
            <a href={item.href} class="text-base text-gray-400 hover:text-gray-300">
              {item.name}
            </a>
          </div>
        ))
      }
    </nav>
    <p class="mt-8 text-center text-base text-gray-400">
      &copy; {year} {pagesConfig.title}
      <br />
      <a
        href={`mailto:${pagesConfig.defaultEmail}`}
        class="inline-block py-1 hover:text-gray-300"
      >
        {pagesConfig.defaultEmail}
      </a>
      {
        Boolean(pagesConfig.defaultPhone) && (
          <>
            <br />
            <a
              href={`tel:${pagesConfig.defaultPhone.replace(/[^+\d]/g, '')}`}
              class="inline-block py-1 hover:text-gray-300"
            >
              {pagesConfig.defaultPhone}
            </a>
          </>
        )
      }
    </p>
    {
      footerLines.length > 0 && (
        <p class="mt-6 text-center text-sm text-gray-400">
          {footerLines.map((line) => (
            <>
              {line}
              <br />
            </>
          ))}
        </p>
      )
    }
  </div>
</footer>

Source links point to engine-astro@e857a859. Samples are cut from the sites' own content by scripts/gallery-extract.mjs; nothing is merged or removed yet.