Astro企业官网

venue-landing-kit — Astro 企业官网模板

作者 NikoAuso

基于 Astro SSR 的多业态落地页工具包,提供组件目录与泳池、餐饮、酒吧、酒店四套预设,可通过 HTTP 后端或提交文件获取数据,并内置演示模式。

看看你的网站会是什么样

浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。

1 个预览视图
作者提供的预览
作者提供的预览首屏预览

来自项目 README 的原始预览。

目前有 1 张原始预览,可打开完整图片查看设计细节。

截图用于了解视觉与布局,交互效果请以实际项目为准。

采集于 2026-10-13查看来源

值得关注的模板亮点

从已有项目资料中,快速了解它的特点。

01

提供 piscina、ristorazione、bar、hotel 四套垂直预设,共享同一组件目录,仅替换 presets/ 下的内容、主题与演示数据

02

数据源可在 backend 与 static 之间切换,hours 和 pricing 等 section 支持单独覆盖,DEMO_MODE 强制静态并内置演示数据

03

section 目录包含 hero、features、hours、pricing、services、rules、highlight、menu、gallery、faq、testimonials、location、story、rooms 等类型,通过数组顺序控制页面结构

04

主题使用 brand-、cta-、accent- 语义 token,主题文件必须位于 Tailwind @import 图中,调色板不支持运行时替换

05

提供 /demo/<preset> 预览路由,在 DEMO_MODE 下可查看全部预设,非演示模式返回 404

06

代码采用 MIT 许可,可免费使用、修改、商用和分发,但需保留版权声明与许可声明

模板详细介绍

Venue Landing Kit 是一个面向本地商业场所的 Astro SSR 落地页模板。它把页面拆成可组合的 section 目录,并附带四套垂直预设:piscina(泳池)、ristorazione(餐饮)、bar(酒吧)、hotel(酒店)。四套预设共享同一套组件,仅通过 presets/ 下的内容、主题与演示数据文件区分。

数据来源支持两种方式:在 site.config.ts 中声明 dataSource 为 backend 或 static,hours 与 pricing 等 section 还可单独覆盖。静态模式下数据来自 site.content.ts 导出的 STATIC_DATA,默认使用预设的演示数据,需要替换为真实数据;后端模式下通过 API_BASE_URL 与 FACILITY_SLUG 拼接端点获取实时数据。DEMO_MODE=true 会强制所有数据走静态路径。

模板还提供 /demo/<preset> 预览路由,在 DEMO_MODE 下可查看全部四套预设,非演示模式返回 404。主题通过语义 token(brand-、cta-、accent-)控制,主题文件必须位于 Tailwind 的 @import 图中,因此调色板不能在运行时替换。选择预设需要同时修改 site.content.ts 的内容导入和 src/styles/tokens.css 的主题导入,两者必须指向同一垂直。

组件目录覆盖 hero、features、hours、pricing、services、rules、highlight、menu、gallery、faq、testimonials、location、story、rooms 等 section,每个 section 只接收 { id, content } 以及必要的 site 或后端 payload。页面顺序由 section 数组顺序决定,设置 enabled: false 可关闭某个 section 及其菜单和锚点。

使用前需要自行替换品牌资产、预设照片与法律文本,并核对演示图片、字体、图标等第三方素材的许可。代码采用 MIT 许可,可免费使用、修改、商用和分发,但外部服务与第三方素材可能另有费用或授权要求。

Astro企业官网

适合你的项目吗?

适用场景

  • 为泳池、餐厅、酒吧或酒店等本地场所搭建单页落地页,并按垂直选择对应预设
  • 已有 HTTP 后端提供营业时间、价格、地址等数据时,通过 API_BASE_URL 与 FACILITY_SLUG 接入实时数据
  • 没有后端或希望完全静态部署时,使用 STATIC_DATA 提交数据文件,构建自包含站点
  • 在 DEMO_MODE 下通过 /demo/<preset> 预览四套预设的页面结构与配色,再决定采用哪一套
  • 基于同一组件目录做白标定制,替换品牌资产、文案与法律文本后用于不同客户

适合人群

  • 需要快速搭建本地商业场所落地页的前端开发者
  • 希望以组件化方式组合页面 section 并控制数据来源的 Astro 项目
  • 已有 HTTP 后端接口、需要将营业时间与价格等数据接入前端的团队
  • 需要多套垂直预设作为起点、再进行白标定制的建站者

上手与定制指南

结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。

  1. 1

    克隆仓库后执行 npm install,复制 .env.example 为 .env(其中 DEMO_MODE=true),再运行 npm run dev 启动本地开发

  2. 2

    选择预设需同时修改 site.content.ts 的内容导入与 src/styles/tokens.css 的主题导入,两者必须指向同一垂直

  3. 3

    静态模式下需替换 site.content.ts 中 STATIC_DATA 的默认演示数据为真实数据;后端模式需配置 API_BASE_URL、FACILITY_SLUG 及可选的 API_AUTH_TOKEN

  4. 4

    替换 public/brand/ 下的品牌资产与预设照片,并重写 src/content/legal/ 中的法律文本;OG 图片必须为 1200×630 的栅格图

  5. 5

    演示图片、字体、图标等第三方素材需按各自许可核对,外部服务可能另行收费

查看仓库使用说明

授权与来源资料

使用条件与限制

免费使用 · 保留许可声明

本次收录的是公开仓库中采用 MIT 许可的免费版本;免费范围为该版本代码,不代表外部服务或第三方素材免费。

使用时需要遵守

  • 允许免费使用、修改、商用和分发该版本代码。
  • 分发代码副本或实质性部分时,保留原作者版权声明和完整 MIT 许可声明。
  • 代码按现状提供;担保与责任限制以原许可证及适用法律为准。

额外费用与待核对事项

  • 演示图片、字体、图标及其他第三方素材需按各自许可核对,不能仅凭代码的 MIT 许可判断。
  • 域名、托管、数据库、支付或 AI 等外部服务可能另外收费。
  • 主题文件必须放在 Tailwind 的 @import 图中;由于带透明度的工具类在构建时内联颜色,调色板无法在运行时替换。
  • 选择预设必须同时修改两处 import(site.content.ts 的内容导入与 tokens.css 的主题导入),且两者必须指向同一垂直;配置中没有 preset 字段。
  • /demo/<preset> 预览路由为 noindex,且在非 DEMO_MODE 下返回 404;正式部署只服务单一预设,不暴露其他预设。
  • 静态模式下数据来自 site.content.ts 导出的 STATIC_DATA,默认是预设的演示数据,必须替换为真实数据。
  • 后端/混合模式下需配置 API_AUTH_TOKEN,作为每次请求的 Bearer 令牌(/up 除外),且仅限服务端使用。
  • PUBLIC_SITE_URL 为必填环境变量,用于 canonical、sitemap 与 OG。
  • OG 图片必须保持 1200×630 的栅格格式,社交爬虫不渲染 SVG。
  • 需自行重写 src/content/legal/ 下的法律文本(Markdown),后端数据时数据控制者来自 site.gdpr,并需通过校验。
  • 需替换 public/brand/ 下的品牌资产以及预设照片。
  • DEMO_MODE=true 会强制所有数据源走静态路径。
查看原文依据

Permission is hereby granted, free of charge

许可证原文

Il tema DEVE stare in quel `@import` (dentro il grafo Tailwind): le utility con opacità inlineano il colore al build, quindi la palette non è sostituibile a runtime.

README 原文

La selezione sono **due import che devono puntare allo stesso verticale** (non esiste un campo `preset` in config, di proposito: sarebbe una terza dichiarazione libera di divergere dalle due che fanno fede):

README 原文

Le route sono `noindex` e **fuori da DEMO_MODE rispondono 404**: un deploy reale serve un solo preset e non espone gli altri.

README 原文

In modalità statica i payload arrivano da `STATIC_DATA` (esportata da `site.content.ts`, default: i dati demo del preset — sostituiscili coi dati reali)

README 原文

`API_AUTH_TOKEN` | solo backend/mixed | — | Bearer su ogni chiamata (non `/up`); server-only |

README 原文

`PUBLIC_SITE_URL` | sì | `http://localhost:4321` | canonical, sitemap, OG |

README 原文

l'OG **deve** restare raster 1200×630 — i crawler social non rendono SVG

README 原文

Riscrivi i legali in `src/content/legal/` (Markdown; il titolare arriva da `site.gdpr` quando i dati sono backend) e falli validare.

README 原文

Sostituisci gli asset: `public/brand/` (identità) e le foto del preset.

README 原文

`DEMO_MODE=true` forza static ovunque.

README 原文
https://github.com/NikoAuso/venue-landing-kit/blob/main/LICENSEhttps://github.com/NikoAuso/venue-landing-kit/blob/main/README.md

DeepSeek 根据仓库许可证和 README 整理 ·2026-10-13。结果仅覆盖已读取资料,依赖、图片、字体及后续条款变更以各自原文为准。

项目核对记录与介绍依据

模板资料

来源平台
GitHub
资料与维护参考分
资料一般 · 68 / 100
技术栈
Astro
网站类型
企业官网
这个分数如何计算

本站按许可资料(最高30分)、演示链接(12分)、预览图(10分)、Star数(15分)、记录的维护时间(15分)、描述完整度(8分)、功能记录(5分)和分类资料(5分)计算。它不是代码、安全或性能测试,也不是 Google 评分;有链接不代表已实测可用。

这个项目需要核对什么

记录的仓库更新时间
2026-10-09
截图检查日期
2026-10-13

目前没有记录演示链接。请依据仓库说明在本地评估;仅凭截图无法确认交互行为。

目录记录的主要技术栈是 Astro。请通过依赖清单和锁文件核对实际版本与托管要求。这些说明基于收录资料,不代表代码审计或部署实测。

查看具体选型方法 →

介绍的制作与核对状态

介绍由 AI 辅助整理目录与仓库资料。仓库作者不等于这篇介绍的审核者。

审核声明: [email protected] · 2026-10-13

查看当时使用的来源资料

SHA-256: b08d031cd2596091e37e47f7492e9fae2f40a6f74e116023516ad5826f45cdb2

2026-10-13T01:36:26.327Z

来源文件 / 仓库
# Venue Landing Kit

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](./LICENSE)

Un kit Astro SSR per landing di attività locali: un **catalogo di componenti** e un **preset pronto
per verticale** — piscina, ristorazione, bar, hotel — customizzabile via file di config. I dati vivi
(identità, orari, listino) possono arrivare **da un backend HTTP** o **da file committati**, sezione
per sezione: un deploy senza gestionale è un sito statico puro.

## I quattro preset

<table>
<tr>
<td width="50%"><b>piscina</b> — ingressi, ombrelloni, regolamento · <a href=".github/screenshots/preset-piscina.jpg">pagina intera</a><br><img src=".github/screenshots/hero-piscina.jpg" alt="Preset piscina"></td>
<td width="50%"><b>ristorazione</b> — carta, storia, galleria · <a href=".github/screenshots/preset-ristorazione.jpg">pagina intera</a><br><img src=".github/screenshots/hero-ristorazione.jpg" alt="Preset ristorazione"></td>
</tr>
<tr>
<td><b>bar</b> — drink list, eventi, dehors · <a href=".github/screenshots/preset-bar.jpg">pagina intera</a><br><img src=".github/screenshots/hero-bar.jpg" alt="Preset bar"></td>
<td><b>hotel</b> — camere e tariffe, servizi · <a href=".github/screenshots/preset-hotel.jpg">pagina intera</a><br><img src=".github/screenshots/hero-hotel.jpg" alt="Preset hotel"></td>
</tr>
</table>

Stessa base di componenti, quattro palette e quattro strutture: cambiano solo i file sotto
`presets/`. Le immagini sono generate dalle route `/demo/<preset>` con `npm run screenshots`.

**Il contratto è il codice**: [`src/lib/dto.ts`](src/lib/dto.ts) (endpoint dati live) e
[`src/lib/sections.ts`](src/lib/sections.ts) (catalogo sezioni e shape della struttura). Lo specchio
leggibile del contratto backend è [`BACKEND_CONTRACT.md`](BACKEND_CONTRACT.md).

## Quickstart (demo, zero backend)

```bash
git clone <questo-repo> && cd <cartella>
npm install
cp .env.example .env   # contiene DEMO_MODE=true
npm run dev            # http://localhost:4321
```

Vedrai il preset attivo (piscina) popolato dai suoi dati demo. `curl localhost:4321/health` →
`{"status":"ok",...,"demo":true,"data_source":"demo",...}`.

### Vetrina dei preset (`/demo/<preset>`)

Per vedere **tutti** i verticali senza toccare i due import, con `DEMO_MODE=true` ogni preset ha la
sua pagina di esempio, servita dallo stesso build:

```bash
npm run dev
open http://localhost:4321/demo/piscina       # oppure ristorazione, bar, hotel
```

| Route                | Cosa mostra                                                     |
| -------------------- | --------------------------------------------------------------- |
| `/demo/piscina`      | preset piscina: copy, dati demo e palette di `presets/piscina/` |
| `/demo/ristorazione` | idem per `presets/ristorazione/`                                |
| `/demo/bar`          | idem per `presets/bar/`                                         |
| `/demo/hotel`        | idem per `presets/hotel/`                                       |

Ogni pagina ha una barra in alto per passare da un preset all'altro; menu e ancore restano sulla
pagina demo (`/demo/bar#orari`). Le route sono `noindex` e **fuori da DEMO_MODE rispondono 404**: un
deploy reale serve un solo preset e non espone gli altri.

Come funziona: la route legge `presets/<nome>/index.ts` (contenuto + `DEMO_DATA`) e inietta il
`theme.css` del preset come `<style>` inline, così i token `brand-`/`cta-`/`accent-` vengono
rivalorizzati a richiesta sopra la palette compilata. Un preset nuovo sotto `presets/` compare da
solo. Per il build reale resta valida la regola dei due import (sotto): la vetrina è solo uno
strumento di anteprima. Anche sul build di produzione:

```bash
npm run build && DEMO_MODE=true node ./dist/server/entry.mjs
curl -s -o /dev/null -w '%{http_code}\n' localhost:4321/demo/hotel   # 200
```

## Come è organizzato

| Superficie        | Possiede                                                                                                              |
| ----------------- | --------------------------------------------------------------------------------------------------------------------- |
| `presets/<tema>/` | il verticale: `content.ts` (struttura+copy), `theme.css` (palette), `demo-data.ts`, asset in `public/presets/<tema>/` |
| `site.content.ts` | il file del **deploy**: importa il preset scelto e applica override per sezione; esporta `STATIC_DATA`                |
| `site.config.ts`  | identità per-deploy: `dataSource`, brand asset, `formatting.{locale,currency}`, analytics, fetch                      |
| `src/`            | componenti, degradazione, sicurezza — mai copy di business, mai palette cablata                                       |

### Scegliere il preset

La selezione sono **due import che devono puntare allo stesso verticale** (non esiste un campo
`preset` in config, di proposito: sarebbe una terza dichiarazione libera di divergere dalle due che
fanno fede):

1. il contenuto, in `site.content.ts`:
   ```ts
   import { content as presetContent } from './presets/ristorazione';
   ```
2. il tema, in `src/styles/tokens.css`:
   ```css
   @import '../../presets/ristorazione/theme.css';
   ```

Il tema DEVE stare in quel `@import` (dentro il grafo Tailwind): le utility con opacità inlineano
il colore al build, quindi la palette non è sostituibile a runtime.

### La struttura a sezioni

`site.content.ts` (via preset) è un `SiteContent`: `meta` + un array ordinato di sezioni. Riordinare
l'array riordina la pagina; `{ type, enabled: false }` spegne una sezione (menu e ancore compresi)
senza richiedere altro. Il catalogo:

| `type`         | Componente     | Dati backend                                |
| -------------- | -------------- | ------------------------------------------- |
| `hero`         | Hero           | `links.booking` (CTA)                       |
| `features`     | FeatureGrid    | —                                           |
| `hours`        | OpeningHours   | `/site/opening-hours` (o statici)           |
| `pricing`      | PricingTables  | `/site/pricing` (o statici)                 |
| `services`     | ServiceList    | —                                           |
| `rules`        | RuleGroups     | `links.booking`, `contacts.whatsapp` (CTA)  |
| `highlight`    | HighlightPanel | `links.booking` (CTA)                       |
| `menu`         | MenuCourses    | — (prezzi come stringhe libere dell'autore) |
| `gallery`      | GalleryGrid    | — (testo tutto opzionale)                   |
| `faq`          | Faq            | — (`<details>` nativi, niente script)       |
| `testimonials` | Testimonials   | — (citazioni redazionali)                   |
| `location`     | Location       | `site.address` (indirizzo + link Maps)      |
| `story`        | Story          | —                                           |
| `rooms`        | RoomsGrid      | `links.booking` (CTA prenota per camera)    |

### I componenti, uno per uno

Screenshot dai preset demo. Ogni sezione prende solo `{ id, content }` (più `site` o i payload backend
dove indicato sopra): l'aspetto è il tema attivo, il testo è il contenuto del preset.

<table>
<tr>
<td width="50%"><b><code>hero</code></b> — titolo, CTA e card laterale: voci con icona = lista di vantaggi, senza icona = passi numerati<br><img src=".github/screenshots/hero-hotel.jpg" alt="Hero"></td>
<td width="50%"><b><code>features</code></b> — griglia di icone + contatori animati<br><img src=".github/screenshots/section-features.jpg" alt="Features"></td>
</tr>
<tr>
<td><b><code>hours</code></b> — settimana dal backend, badge sul giorno corrente, card stagione<br><img src=".github/screenshots/section-hours.jpg" alt="Orari"></td>
<td><b><code>pricing</code></b> — listino ingressi e abbonamenti dal backend<br><img src=".github/screenshots/section-pricing.jpg" alt="Prezzi"></td>
</tr>
<tr>
<td><b><code>menu</code></b> — categorie ad accordion, tab opzionali, link al menu esterno<br><img src=".github/screenshots/section-menu.jpg" alt="Menu"></td>
<td><b><code>rooms</code></b> — card camera con dotazioni, prezzo "da" e CTA prenota<br><img src=".github/screenshots/section-rooms.jpg" alt="Camere"></td>
</tr>
<tr>
<td><b><code>services</code></b> — due foto affiancate a un elenco di servizi<br><img src=".github/screenshots/section-services.jpg" alt="Servizi"></td>
<td><b><code>rules</code></b> — regolamento in gruppi, con toni ammesso/vietato<br><img src=".github/screenshots/section-rules.jpg" alt="Regolamento"></td>
</tr>
<tr>
<td><b><code>highlight</code></b> — pannello scuro per un'area o un'iniziativa<br><img src=".github/screenshots/section-highlight.jpg" alt="Highlight"></td>
<td><b><code>gallery</code></b> — griglia foto con celle larghe, flusso denso (niente buchi)<br><img src=".github/screenshots/section-gallery.jpg" alt="Galleria"></td>
</tr>
<tr>
<td><b><code>story</code></b> — foto affiancata a qualche paragrafo di racconto<br><img src=".github/screenshots/section-story.jpg" alt="Storia"></td>
<td><b><code>testimonials</code></b> — citazioni con autore e valutazione<br><img src=".github/screenshots/section-testimonials.jpg" alt="Recensioni"></td>
</tr>
<tr>
<td><b><code>faq</code></b> — domande in <code>&lt;details&gt;</code> nativi, senza JavaScript<br><img src=".github/screenshots/section-faq.jpg" alt="FAQ"></td>
<td><b><code>location</code></b> — indirizzo e link Maps dal backend, più come arrivare<br><img src=".github/screenshots/section-location.jpg" alt="Dove siamo"></td>
</tr>
</table>

### Fonte dati: backend, statica, o mista

`site.config.ts` dichiara `dataSource: 'backend' | 'static'`; le sezioni `hours`/`pricing` possono
fare override con `data.source`. In modalità statica i payload arrivano da `STATIC_DATA`
(esportata da `site.content.ts`, default: i dati demo del preset — sostituiscili coi dati reali) e
**non esiste il percorso 503**: il sito è self-contained. `DEMO_MODE=true` forza static ovunque.
`/health` riporta `data_source: 'backend' | 'static' | 'demo' | 'mixed'` e degrada solo se il
deploy dipende davvero da un backend giù.

## White-labeling di un deploy

1. Fork; scegli il preset (i due import sopra).
2. Override di copy in `site.content.ts` (sostituzione esplicita per sezione — esempio nel file).
3. `site.config.ts`: `dataSource`, `formatting`, asset brand (`logoUrl`/`faviconUrl`/`ogImageUrl`
   accettano URL assoluto o path da `public/`; l'OG **deve** restare raster 1200×630 — i crawler
   social non rendono SVG).
4. Sostituisci gli asset: `public/brand/` (identità) e le foto del preset.
5. Riscrivi i legali in `src/content/legal/` (Markdown; il titolare arriva da `site.gdpr` quando i
   dati sono backend) e falli validare.
6. Env del deploy:

   | Var                         | Richiesta          | Default                               | Uso                                                                   |
   | --------------------------- | ------------------ | ------------------------------------- | --------------------------------------------------------------------- |
   | `DEMO_MODE`                 | no                 | `false`                               | `true` = serving statico coi dati demo del preset                     |
   | `API_BASE_URL`              | solo backend/mixed | `http://127.0.0.1:8000/api/public/v1` | root del backend; URL = `${API_BASE_URL}/${FACILITY_SLUG}/<endpoint>` |
   | `FACILITY_SLUG`             | solo backend/mixed | `demo`                                | struttura servita; verificato contro `SitePayload.slug` (warning)     |
   | `API_AUTH_TOKEN`            | solo backend/mixed | —                                     | Bearer su ogni chiamata (non `/up`); server-only                      |
   | `PUBLIC_SITE_URL`           | sì                 | `http://localhost:4321`               | canonical, sitemap, OG                                                |
   | `CACHE_TTL_SECONDS`         | no                 | `300`                                 | TTL cache in-process                                                  |
   | `PUBLIC_GA4_MEASUREMENT_ID` | no                 | —                                     | GA4 consent-mode v2 (vuoto = niente tag)                              |
   | `PORT` / `HOST`             | no                 | default Astro                         | bind del server                                                       |

7. Build e avvio:
   ```bash
   npm ci && npm run build
   node ./dist/server/entry.mjs   # env dal process manager, non da .env
   ```
   PM2/systemd per i restart; Nginx/Caddy davanti per TLS e per servire `dist/client/`.
   Smoke-test: `curl https://<sito>/health`.

## Comandi

| Comando                               | Scopo                                                          |
| ------------------------------------- | -------------------------------------------------------------- |
| `npm run dev` / `build` / `preview`   | dev server · build SSR · esecuzione del build con `.env`       |
| `npm run check`                       | `astro check` + `tsc --noEmit`                                 |
| `npm run lint` / `format`             | ESLint · Prettier (`format:check` è gate CI)                   |
| `npm test`                            | unit (Vitest) — include le guardie su temi, wiring e contratto |
| `npm run test:e2e[:degraded\|:empty]` | Playwright su mock backend / backend giù / payload vuoti       |
| `npm run test:lh`                     | Lighthouse (manuale, non gate CI)                              |
| `npm run screenshots`                 | rigenera `.github/screenshots/` dalle route `/demo/<preset>`   |

Le suite E2E derivano le attese dalla struttura committata: il re-theme non le rompe.

## Contribuire

Vedi [CONTRIBUTING.md](./CONTRIBUTING.md). Sicurezza: [SECURITY.md](./SECURITY.md).
Licenza [MIT](./LICENSE).
反馈内容错误

看看同类模板

对比同技术栈与用途的模板,找到更适合的视觉与内容结构。