ProductItem
apps/www/src/components/ProductItem.astro · 46 lines · group Features & lists
Used by
- pages.gitt.one /how-it-works/ × 4
- pages.gitt.one / × 4
Live sites: pages.gitt.one.
Samples 2
<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}/docsKnowledge 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}/wwwLanding 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><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}/docsKnowledge 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}/wwwLanding 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
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| kicker | string | |||
| title | string | yes | ||
| description | string | |||
| bullets | string[] | [] | ||
| Icon | any |
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.