ProductItem

apps/www/src/components/ProductItem.astro · 46 lines · group Features & lists

Used by

Live sites: pages.gitt.one.

Samples 2

pages.gitt.one/how-it-works/shown inside <ProductSection>

Two builder images, two kinds of website

Pick the image that matches what you are publishing. Everything else — the markdown pipeline, image optimization, SEO files, caching rules — is inherited from it.

{project}/docs

Knowledge bases

The markdown files your team already writes in GitLab, published as a website. Clients read the site instead of walking into your repository.

  • Plain .md and .mdx files, no front matter required
  • README.md becomes the site root, links between .md files are rewritten into slugs
  • Optional intranet mode behind basic auth
{project}/www

Landing pages

Marketing sites with strictly typed content: the structure is fixed, the copy changes often — and changing it never touches the layout.

  • Content written as semantic typed tags in MDX
  • Images, PDFs and other assets served straight from the repository
  • A single pages.config.js per site: title, contacts, logo, locales, menu
MDX of this sample
import BookOpenIcon from 'astro-heroicons/outline/BookOpen.astro';
import GlobeAltIcon from 'astro-heroicons/outline/GlobeAlt.astro';

<ProductSection
  title="Two builder images, two kinds of website"
  description="Pick the image that matches what you are publishing. Everything else — the markdown pipeline, image optimization, SEO files, caching rules — is inherited from it."
>
  <ProductItem
    kicker="{project}/docs"
    title="Knowledge bases"
    description="The markdown files your team already writes in GitLab, published as a website. Clients read the site instead of walking into your repository."
    Icon={BookOpenIcon}
    bullets={[
      'Plain .md and .mdx files, no front matter required',
      'README.md becomes the site root, links between .md files are rewritten into slugs',
      'Optional intranet mode behind basic auth',
    ]}
  />
  <ProductItem
    kicker="{project}/www"
    title="Landing pages"
    description="Marketing sites with strictly typed content: the structure is fixed, the copy changes often — and changing it never touches the layout."
    Icon={GlobeAltIcon}
    bullets={[
      'Content written as semantic typed tags in MDX',
      'Images, PDFs and other assets served straight from the repository',
      'A single pages.config.js per site: title, contacts, logo, locales, menu',
    ]}
  />
</ProductSection>
pages.gitt.one/shown inside <ProductSection>

Two kinds of website, one production line

Whatever you publish, the engine arrives as a ready-made builder image and your repository stays down to content plus a few lines of Dockerfile.

{project}/docs

Knowledge bases

The markdown your team already writes in GitLab, published as a website. Clients read the site instead of walking into your repository.

  • Plain .md files — no front matter, no rewriting for the web
  • A page looks the same in the repository and on the public site
  • Publish to the world or keep it intranet behind basic auth
{project}/www

Landing pages

Marketing sites with strictly typed content: the structure is fixed, the copy changes often — and changing it never touches the layout.

  • Content written as semantic typed tags, separate from the design
  • Edited by a content manager, an AI agent, or both
  • One config file per site: title, contacts, logo, locales, menu
MDX of this sample
import BookOpenIcon from 'astro-heroicons/outline/BookOpen.astro';
import GlobeAltIcon from 'astro-heroicons/outline/GlobeAlt.astro';

<ProductSection
  title="Two kinds of website, one production line"
  description="Whatever you publish, the engine arrives as a ready-made builder image and your repository stays down to content plus a few lines of Dockerfile."
>
  <ProductItem
    kicker="{project}/docs"
    title="Knowledge bases"
    description="The markdown your team already writes in GitLab, published as a website. Clients read the site instead of walking into your repository."
    Icon={BookOpenIcon}
    bullets={[
      'Plain .md files — no front matter, no rewriting for the web',
      'A page looks the same in the repository and on the public site',
      'Publish to the world or keep it intranet behind basic auth',
    ]}
  />
  <ProductItem
    kicker="{project}/www"
    title="Landing pages"
    description="Marketing sites with strictly typed content: the structure is fixed, the copy changes often — and changing it never touches the layout."
    Icon={GlobeAltIcon}
    bullets={[
      'Content written as semantic typed tags, separate from the design',
      'Edited by a content manager, an AI agent, or both',
      'One config file per site: title, contacts, logo, locales, menu',
    ]}
  />
</ProductSection>

Props

NameTypeRequiredDefaultDescription
kickerstring
titlestringyes
descriptionstring
bulletsstring[][]
Iconany

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

---
interface Props {
  kicker?: string;
  title: string;
  description?: string;
  bullets?: string[];
  Icon?: any;
}

const { kicker, title, description, bullets = [], Icon } = Astro.props;
---

<div class="flex h-full flex-col rounded-2xl border border-gray-200 bg-gray-50 p-8">
  <div class="flex items-center">
    <span
      class="flex h-12 w-12 items-center justify-center rounded-md bg-gradient-to-r from-primary-500 to-primary-alt-600"
    >
      {Icon && <Icon class="h-6 w-6 text-white" aria-hidden="true" />}
    </span>
    {
      kicker && (
        <code class="ml-4 rounded bg-white px-2 py-1 font-mono text-sm text-primary-700 ring-1 ring-inset ring-primary-100">
          {kicker}
        </code>
      )
    }
  </div>
  <h3 class="mt-6 text-xl font-bold text-gray-900">{title}</h3>
  {description && <p class="mt-3 text-base text-gray-500">{description}</p>}
  {
    bullets.length > 0 && (
      <ul class="mt-6 space-y-3 text-base text-gray-500">
        {bullets.map((bullet) => (
          <li class="flex">
            <span
              aria-hidden="true"
              class="mr-3 mt-2 h-1.5 w-1.5 flex-none rounded-full bg-gradient-to-r from-primary-500 to-primary-alt-600"
            />
            <span>{bullet}</span>
          </li>
        ))}
      </ul>
    )
  }
</div>

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.