# 🚀 Astro Docker Kit
## 🚀 Quick Start ```bash git clone https://github.com/advento-ir/astro-docker-kit cd astro-docker-kit npm install npm run dev ``` Visit `http://localhost:4321`. --- ## 🐳 Deploy with Docker ```bash cp .env.example .env docker network create private-net # required once docker compose up -d ``` --- ## 📁 Project Structure ```text / ├── public/fonts/iran-yekan-x/ # IRANYekanX woff2 files ├── src/ │ ├── components/ │ │ ├── blocks/ # Content block components │ │ ├── core/ # Base UI components │ │ ├── layout/ # Header, footer, sidebar │ │ └── meta/SEO.astro # SEO component │ ├── layouts/BaseLayout.astro # RTL/FA base layout │ ├── pages/index.astro # Homepage │ └── styles/ │ ├── fonts.css # Persian font definitions │ └── global.css # Global styles + Tailwind ├── Dockerfile ├── docker-compose.yml └── nginx.conf ``` --- ## 🔍 SEO Component `src/components/meta/SEO.astro` is a full-featured, drop-in SEO component used inside `BaseLayout.astro`. It handles every layer of modern SEO — from core meta tags to structured data — with zero external dependencies. ### Features at a glance | Category | What's included | | --- | --- | | Core meta | ``, `description`, `keywords`, `author`, `robots`, `theme-color`, `color-scheme`, `generator` | | Canonical | Auto-detected from `Astro.url.href` or manually overridden | | Open Graph | `og:type`, `og:title`, `og:description`, `og:image` (+ width/height/alt), `og:locale`, `og:site_name` | | OG Article | `article:published_time`, `article:modified_time`, `article:section`, `article:tag`, `article:author` | | Twitter Card | `twitter:card`, `twitter:title`, `twitter:description`, `twitter:image`, `twitter:site`, `twitter:creator` | | JSON-LD | Auto-generated `WebSite`, `WebPage` / `Article`, `BreadcrumbList` schemas + custom schema injection | | hreflang | Alternate locale `<link>` tags for multilingual sites | | Resource hints | `preconnect` and `dns-prefetch` link tags | | Favicon | SVG icon, ICO fallback, Apple touch icon, Web App Manifest | --- ### Basic usage `BaseLayout.astro` already wires the component up — just pass props when using the layout: ```astro --- import BaseLayout from '../layouts/BaseLayout.astro'; --- <BaseLayout title="My Page" description="A short description of this page." /> ``` All other props are optional and tree-shake to nothing when unused. --- ### All props #### Core | Prop | Type | Default | Description | | --- | --- | --- | --- | | `title` | `string` | **required** | Page title (also used as OG/Twitter fallback) | | `titleTemplate` | `string` | `'%s'` | Wraps the title — `%s` is replaced with `title`. E.g. `'%s \| Advento'` | | `description` | `string` | **required** | Meta description (also used as OG/Twitter fallback) | | `keywords` | `string[]` | — | Comma-joined into `<meta name="keywords">` | | `author` | `string` | — | `<meta name="author">` | | `themeColor` | `string` | `'#7c3aed'` | `<meta name="theme-color">` | #### Canonical & Robots | Prop | Type | Default | Description | | --- | --- | --- | --- | | `canonical` | `string` | `Astro.url.href` | Absolute canonical URL | | `noindex` | `boolean` | `false` | Add `noindex` to the robots directive | | `nofollow` | `boolean` | `false` | Add `nofollow` to the robots directive | #### Open Graph | Prop | Type | Default | Description | | --- | --- | --- | --- | | `ogType` | `'website' \| 'article' \| 'profile'` | `'website'` | OG object type | | `ogTitle` | `string` | resolved `title` | Override OG title | | `ogDescription` | `string` | `description` | Override OG description | | `ogImage` | `string` | — | Absolute URL to the OG image (1200×630 recommended) | | `ogImageAlt` | `string` | — | Alt text for the OG image | | `ogImageWidth` | `number` | `1200` | OG image width in pixels | | `ogImageHeight` | `number` | `630` | OG image height in pixels | | `ogLocale` | `string` | `'fa_IR'` | OG locale string | | `ogSiteName` | `string` | — | `og:site_name` | #### Twitter Card | Prop | Type | Default | Description | | --- | --- | --- | --- | | `twitterCard` | `'summary' \| 'summary_large_image' \| 'app' \| 'player'` | `'summary_large_image'` | Card type | | `twitterSite` | `string` | — | Site Twitter handle (e.g. `@advento_ir`) | | `twitterCreator` | `string` | — | Author Twitter handle | | `twitterTitle` | `string` | OG title | Override Twitter title | | `twitterDescription` | `string` | OG description | Override Twitter description | | `twitterImage` | `string` | OG image | Override Twitter image URL | | `twitterImageAlt` | `string` | — | Alt text for the Twitter image | #### Article (requires `ogType="article"`) Pass an `article` object with the following shape: ```ts interface ArticleMeta { publishedTime: string; // ISO 8601, e.g. "2025-01-15T10:00:00Z" modifiedTime?: string; authors?: string[]; // names or profile URLs section?: string; tags?: string[]; } ``` #### JSON-LD & Breadcrumbs | Prop | Type | Description | | --- | --- | --- | | `breadcrumbs` | `BreadcrumbItem[]` | Generates a `BreadcrumbList` schema automatically | | `jsonLd` | `Record<string, unknown> \| Record<string, unknown>[]` | Inject one or more custom schema.org objects | ```ts interface BreadcrumbItem { name: string; url: string; // absolute URL } ``` #### Alternates & Resource Hints | Prop | Type | Description | | --- | --- | --- | | `alternateLocales` | `AlternateLocale[]` | Emits `<link rel="alternate" hreflang="...">` for each entry | | `preconnect` | `string[]` | Emits `<link rel="preconnect">` for each origin | | `dnsPrefetch` | `string[]` | Emits `<link rel="dns-prefetch">` for each origin | ```ts interface AlternateLocale { hreflang: string; // e.g. "en", "fa", "x-default" href: string; // absolute URL } ``` #### Favicon & Manifest | Prop | Type | Default | Description | | --- | --- | --- | --- | | `faviconSvg` | `string` | `'/favicon.svg'` | Path to SVG favicon | | `faviconIco` | `string` | — | Path to `.ico` favicon (legacy browsers) | | `appleTouchIcon` | `string` | — | Path to Apple touch icon (180×180 PNG) | | `manifestHref` | `string` | — | Path to `manifest.json` / `manifest.webmanifest` | --- ### Full example — article page ```astro --- import BaseLayout from '../layouts/BaseLayout.astro'; --- <BaseLayout title="How We Built This Kit" titleTemplate="%s | Advento" description="A deep-dive into our Astro + Docker starter setup." keywords={['Astro', 'Docker', 'Tailwind', 'RTL']} author="Advento Team" canonical="https://advento.ir/blog/how-we-built-this-kit" ogType="article" ogImage="https://advento.ir/og/how-we-built-this-kit.png" ogImageAlt="Screenshot of the Astro Docker Kit starter" ogSiteName="Advento" twitterSite="@advento_ir" twitterCreator="@advento_ir" article={{ publishedTime: '2025-01-15T10:00:00Z', modifiedTime: '2025-06-01T08:00:00Z', authors: ['Advento Team'], section: 'Engineering', tags: ['Astro', 'Docker', 'SEO'], }} breadcrumbs={[ { name: 'Home', url: 'https://advento.ir' }, { name: 'Blog', url: 'https://advento.ir/blog' }, { name: 'How We Built This Kit', url: 'https://advento.ir/blog/how-we-built-this-kit' }, ]} alternateLocales={[ { hreflang: 'fa', href: 'https://advento.ir/fa/blog/how-we-built-this-kit' }, { hreflang: 'x-default', href: 'https://advento.ir/blog/how-we-built-this-kit' }, ]} preconnect={['https://fonts.gstatic.com']} /> ``` --- ## 🧞 Commands | Command | Action | | ---------------------- | ------------------------------------ | | `npm run dev` | Start dev server at `localhost:4321` | | `npm run build` | Build production site to `./dist/` | | `npm run preview` | Preview the production build locally | | `npm run format` | Format code with Prettier | | `npm run lint` | Lint with ESLint | | `docker compose up -d` | Run container in background | --- ## 🤝 Contributing 1. Fork the repo 2. Create a branch: `git checkout -b feature/your-feature` 3. Commit: `git commit -m 'feat: add your feature'` 4. Push and open a Pull Request --- ## 🌌 About Advento At [Advento](https://advento.ir), we are redefining the digital marketing landscape. By harnessing the absolute edge of Artificial Intelligence, we deliver highly scalable, data-driven, and innovative solutions. This repository is part of our commitment to pushing the boundaries of what's possible in digital marketing technology. --- ## 📄 License MIT — see [LICENSE](LICENSE) for details. --- <div align="center"> Made with ❤️ by [**Advento**](https://advento.ir) </div>