提供 piscina、ristorazione、bar、hotel 四套垂直预设,共享同一组件目录,仅替换 presets/ 下的内容、主题与演示数据
venue-landing-kit — Astro 企业官网模板
作者 NikoAuso
基于 Astro SSR 的多业态落地页工具包,提供组件目录与泳池、餐饮、酒吧、酒店四套预设,可通过 HTTP 后端或提交文件获取数据,并内置演示模式。
看看你的网站会是什么样
浏览真实页面截图,比较内容排版与手机效果。点击下方缩略图切换,放大查看整页细节。
目前有 1 张原始预览,可打开完整图片查看设计细节。
截图用于了解视觉与布局,交互效果请以实际项目为准。
值得关注的模板亮点
从已有项目资料中,快速了解它的特点。
数据源可在 backend 与 static 之间切换,hours 和 pricing 等 section 支持单独覆盖,DEMO_MODE 强制静态并内置演示数据
section 目录包含 hero、features、hours、pricing、services、rules、highlight、menu、gallery、faq、testimonials、location、story、rooms 等类型,通过数组顺序控制页面结构
主题使用 brand-、cta-、accent- 语义 token,主题文件必须位于 Tailwind @import 图中,调色板不支持运行时替换
提供 /demo/<preset> 预览路由,在 DEMO_MODE 下可查看全部预设,非演示模式返回 404
代码采用 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 许可,可免费使用、修改、商用和分发,但外部服务与第三方素材可能另有费用或授权要求。
适合你的项目吗?
适用场景
- 为泳池、餐厅、酒吧或酒店等本地场所搭建单页落地页,并按垂直选择对应预设
- 已有 HTTP 后端提供营业时间、价格、地址等数据时,通过 API_BASE_URL 与 FACILITY_SLUG 接入实时数据
- 没有后端或希望完全静态部署时,使用 STATIC_DATA 提交数据文件,构建自包含站点
- 在 DEMO_MODE 下通过 /demo/<preset> 预览四套预设的页面结构与配色,再决定采用哪一套
- 基于同一组件目录做白标定制,替换品牌资产、文案与法律文本后用于不同客户
适合人群
- 需要快速搭建本地商业场所落地页的前端开发者
- 希望以组件化方式组合页面 section 并控制数据来源的 Astro 项目
- 已有 HTTP 后端接口、需要将营业时间与价格等数据接入前端的团队
- 需要多套垂直预设作为起点、再进行白标定制的建站者
上手与定制指南
结合仓库当前版本的说明,按下面的资料检查内容、配置与运行要求。
- 1
克隆仓库后执行 npm install,复制 .env.example 为 .env(其中 DEMO_MODE=true),再运行 npm run dev 启动本地开发
- 2
选择预设需同时修改 site.content.ts 的内容导入与 src/styles/tokens.css 的主题导入,两者必须指向同一垂直
- 3
静态模式下需替换 site.content.ts 中 STATIC_DATA 的默认演示数据为真实数据;后端模式需配置 API_BASE_URL、FACILITY_SLUG 及可选的 API_AUTH_TOKEN
- 4
替换 public/brand/ 下的品牌资产与预设照片,并重写 src/content/legal/ 中的法律文本;OG 图片必须为 1200×630 的栅格图
- 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 原文
https://github.com/NikoAuso/venue-landing-kit/blob/main/LICENSEhttps://github.com/NikoAuso/venue-landing-kit/blob/main/README.md`DEMO_MODE=true` forza static ovunque.
README 原文
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)
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><details></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).
看看同类模板
对比同技术栈与用途的模板,找到更适合的视觉与内容结构。

astrowind
⭕️ AstroWind: A free template using Astro v7 and Tailwind CSS v4. Astro starter theme.
Astro · 博客

astro-landing-page
An Astro + Tailwind CSS Example/Template for Landing Pages
Astro · 企业官网

Tailcast
Dark-themed website template built on Astro and Tailwind CSS
Astro · 企业官网

Positivus
A stunning and versatile Astro theme designed for digital marketing agencies.
Astro · 企业官网

qwind
⭕️ Qwind: A template to make your website using Qwik + Tailwind CSS.
Astro · 工具站

agency-landing-page-Astrojs
A simple agency landing page made with astrojs and tailwindcss
Astro · 企业官网
