Skip to content

Commit 13c55c9

Browse files
authored
Merge pull request #5 from libredb/feat/unify-deploy
Unify deploy: single-source content in the shared IDE shell (SEO preserved)
2 parents 92eaa93 + 7354eda commit 13c55c9

13 files changed

Lines changed: 946 additions & 247 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ Any push to the `main` branch will trigger an automatic build and deployment.
3434

3535
- **Live Site**: https://libredb.github.io
3636
- **Main Project**: https://github.com/libredb/libredb-studio
37-
- **Live Demo**: https://demo.libredb.studio
37+
- **Live Demo**: https://app.libredb.org
3838
- **LinkedIn**: https://www.linkedin.com/company/libredb
3939

4040
## License
Lines changed: 139 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,139 @@
1+
# Unify Deploy — single-source content, consistent IDE shell (B2)
2+
3+
> Problem: `/deploy` (a Google-indexed URL) renders as a classic centered
4+
> Header/Footer page, while the homepage Explorer→deploy shows a sparse IDE
5+
> result-set teaser. Two different approaches AND two different content depths.
6+
> Goal: one rich deploy content authored ONCE, shown in the SAME IDE shell both
7+
> on the homepage `#deploy` section and at `/deploy` — without losing `/deploy`'s
8+
> SEO and without duplicating content or the shell.
9+
10+
## Decisions (locked with user, 2026-06-23)
11+
- **B2**: keep `/deploy` as a real, indexed page (do NOT redirect — it's indexed;
12+
a hash `/#deploy` is not a separate indexable URL, so redirecting would
13+
consolidate `/deploy` into the homepage and drop the dedicated URL).
14+
- **Single source, hard requirement**: the deploy *content* is authored exactly
15+
once (in `DeploySection.astro`) and rendered from two places. No second copy.
16+
- **Shared shell**: extract the IDE chrome into `StudioShell.astro` so both pages
17+
use one shell (no shell duplication either).
18+
- Scope: deploy only. Other sub-pages (`/docker-compose-example`,
19+
`/privacy-policy`, `/404`) keep Header/Footer for now (separate future pass).
20+
21+
## Architecture
22+
23+
### 1. `StudioShell.astro` (NEW) — the one IDE chrome
24+
Extracts what `index.astro` currently inlines: desktop `TopBar`, `MobileTopBar`,
25+
the workbench (`<aside>` Explorer sidebar + `<main class="studio-pane">` with a
26+
`<slot/>` for sections), desktop `StatusBar`, `Console`, `CommandPalette`, and the
27+
`<script>import '../scripts/studio.ts'</script>`.
28+
- Props:
29+
- `active: string` — the initially-active section id.
30+
- `standalone?: boolean` (default `false`) — true for focused sub-pages (`/deploy`)
31+
that render a single section; flips Explorer/MobileTopBar links to absolute
32+
`/#{id}` (navigate to the homepage studio) and tells `studio.ts` not to do
33+
in-page swapping.
34+
- Root element carries flags for the script:
35+
`<div class="studio" data-studio data-standalone={standalone ? '' : null} data-initial-active={active}>`.
36+
37+
### 2. `index.astro` (MOD)
38+
Replace the inlined shell with `<StudioShell active="home">` wrapping the existing
39+
8 `<SectionShell>`s in the default slot. No behavior change (home active, in-page
40+
swap, palette, etc. all unchanged). The deploy `SectionShell` now contains the rich
41+
`<DeploySection />` (see §4).
42+
43+
### 3. `deploy.astro` (MOD → thin, ~25 lines)
44+
```
45+
<Layout title={deployTitle} description={deployDescription}>
46+
<Fragment slot="head"><script type="application/ld+json" set:html={ItemList JSON-LD} /></Fragment>
47+
<StudioShell active="deploy" standalone>
48+
<SectionShell section={sectionById['deploy']}><DeploySection /></SectionShell>
49+
</StudioShell>
50+
</Layout>
51+
```
52+
- Keeps its own `<title>`, meta description, automatic canonical (`/deploy`), and
53+
the deploy **ItemList JSON-LD** (deploy-specific structured data — authored once
54+
here; it is metadata, not the visible content, so this is not content duplication).
55+
- Drops `<Header/>`, `<Footer/>`, the centered `<main>` layout, the breadcrumb, and
56+
ALL the inline visible deploy markup (that markup moves into `DeploySection`).
57+
- The build-time `getStars` call and the client star-refresh `<script>` move into
58+
`DeploySection` (single source), so `deploy.astro` does not re-author them.
59+
60+
### 4. `DeploySection.astro` (MOD) — the SINGLE source of deploy content
61+
Becomes the rich content (lifted verbatim from old `deploy.astro`'s body), replacing
62+
the current sparse teaser (5 count-cards + chips + "+N more"):
63+
- Header: `SectionHeader` "Deploy anywhere" + subtitle with `{platformCount}+
64+
platforms and {installMethodCount} install methods`.
65+
- A compact **summary strip** (keep the existing 5 category count-cards as an
66+
at-a-glance band — nice in the IDE result view).
67+
- **Official one-click integrations**: cards for `status === 'official'`
68+
(Railway, CapRover) — logo, blurb, Deploy-now/Install-guide + Docs buttons.
69+
- **Category-grouped platform list**: for each `deployCategory` (ordered) → group
70+
title + tagline + responsive grid of `<PlatformCard target stars=…>`; targets
71+
sorted official→available→planned.
72+
- **Investor band**: "{totalStars}+ GitHub stars" + planned-names line.
73+
- Build-time stars: `const stars = await getStars(starRepos)` in frontmatter,
74+
passed to each `PlatformCard`.
75+
- Client **star-refresh `<script>`** (the `[data-stars-repo]` live-update + total)
76+
lives here too — so it runs wherever `DeploySection` is rendered.
77+
- Rendered by BOTH `index.astro` (homepage `#deploy` pane, scrolls) and
78+
`deploy.astro`. Authored once.
79+
- Internal CTA links (Docker Compose example, GitHub, live demo) kept.
80+
81+
### 5. `Explorer.astro` + `MobileTopBar.astro` (MOD)
82+
Add a `standalone?: boolean` prop. Section links become
83+
`${standalone ? '/' : ''}#${id}``#features` on the homepage (in-page swap),
84+
`/#features` on `/deploy` (navigate home). `MobileTopBar` forwards `standalone` to
85+
its drawer `Explorer`.
86+
87+
### 6. `studio.ts` (MOD) — standalone awareness
88+
- Read flags from `[data-studio]`: `standalone = dataset.standalone !== undefined`;
89+
`initialActive = dataset.initialActive || 'home'`.
90+
- Initial active on load: `location.hash ? currentHash() : initialActive` (so
91+
`/deploy` with no hash activates `deploy`).
92+
- `setActive(id)`: **no-op if `[data-section="${id}"]` is absent** from the DOM
93+
(protects focused pages from blanking on an unknown hash).
94+
- `onLinkClick`: when `standalone`, do NOT `preventDefault` — let the `/#{id}`
95+
anchor navigate to the homepage (no in-page swap on focused pages).
96+
- Command palette "Jump to {section}": when `standalone`, navigate via
97+
`location.href = '/#'+id` instead of setting `location.hash`.
98+
- All other behaviors (toasts, run, copy, export, explain, search) unchanged and
99+
work on `/deploy` (deploy section present).
100+
101+
### 7. `Layout.astro` (MOD)
102+
Add a named `head` slot (`<slot name="head" />` inside `<head>`) so a page can inject
103+
page-specific `<head>` content (deploy's ItemList JSON-LD). Existing global JSON-LD
104+
unchanged. Homepage adds nothing to this slot (no duplicate ItemList across URLs).
105+
106+
## SEO
107+
- `/deploy` keeps its URL, `<title>`, description, self-canonical, and ItemList
108+
JSON-LD → stays indexed; a same-URL design change does not deindex it.
109+
- Homepage JSON-LD unchanged. Deploy content appearing on both `/` (one section
110+
among many) and `/deploy` (focused) is the standard section + dedicated-page
111+
pattern; each self-canonicalises.
112+
- Internal links to `/deploy` (Hero "Deploy in one click", get_started pointer,
113+
Header/Footer "Deploy") stay as `/deploy` (it's a real page).
114+
115+
## Files
116+
```
117+
src/components/studio/StudioShell.astro NEW extracted shell (active, standalone)
118+
src/pages/index.astro MOD use StudioShell active=home + 8 sections
119+
src/pages/deploy.astro MOD thin: Layout(SEO+ItemList) + StudioShell standalone + DeploySection; drop Header/Footer/centered layout & inline deploy markup
120+
src/components/sections/DeploySection.astro MOD rich SINGLE-SOURCE content (summary + official + grouped PlatformCards + investor band) + getStars + star-refresh script
121+
src/components/studio/Explorer.astro MOD standalone -> /#id links
122+
src/components/studio/MobileTopBar.astro MOD forward standalone to drawer Explorer
123+
src/scripts/studio.ts MOD standalone awareness (data flags, setActive bail, link navigate, palette jump)
124+
src/layouts/Layout.astro MOD add named `head` slot
125+
```
126+
Unchanged data: `deploy-targets.ts`, `deploy-categories.ts`, `sections.ts`.
127+
`PlatformCard.astro` / `StatusBadge.astro` now consumed by `DeploySection` (were by `deploy.astro`).
128+
129+
## Success criteria
130+
- The deploy content exists in exactly ONE source file (`DeploySection.astro`);
131+
`index.astro` and `deploy.astro` both render `<DeploySection/>` with no copied markup.
132+
- Homepage `#deploy` and `/deploy` show the same rich content in the same IDE shell.
133+
- `/deploy` still returns 200 at its own URL with its `<title>` + ItemList JSON-LD
134+
(indexing preserved); no redirect.
135+
- On `/deploy`, Explorer/palette navigation to other tables goes to `/#section`;
136+
deploy stays active on load.
137+
- `bunx astro build` passes; homepage and `/deploy` both render; existing homepage
138+
interactions (swap/palette/toasts/etc.) unaffected.
139+
```

0 commit comments

Comments
 (0)