Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
dfc6659
Add email docs and stacks-email templates
abovedave Jun 1, 2026
97dad67
refactor(stacks-email): modernize email engine
abovedave Jun 2, 2026
b58f3d3
feat(stacks-docs): serve static email previews
abovedave Jun 2, 2026
8220ccc
docs(email): update email docs for static previews
abovedave Jun 2, 2026
ecb53cd
run format
abovedave Jun 2, 2026
3d07817
docs
abovedave Jun 2, 2026
ce82f95
fix(stacks-email): resolve json2mjml in dev SSR
abovedave Jun 2, 2026
df08b3c
readme
abovedave Jun 2, 2026
5a42996
fix CJS module import
abovedave Jun 2, 2026
3416529
move fonts to tokens
abovedave Jun 2, 2026
9eef0c0
nicer loading style for embed
abovedave Jun 2, 2026
a7dc768
simplify head injection
abovedave Jun 2, 2026
23b55f1
fix linting errors
abovedave Jun 2, 2026
7bd9258
refactor to avoid the round trips with string vs json object mjml
abovedave Jun 2, 2026
8289b65
remove duplicate code between email and component variants
abovedave Jun 2, 2026
a939f0e
remove duplicated markdown render
abovedave Jun 2, 2026
aa0d3a3
tidy
abovedave Jun 2, 2026
df9ea6c
add strip graphic variant
abovedave Jun 2, 2026
133f545
remove divider placeholder
abovedave Jun 2, 2026
4565a76
no need for explicity default
abovedave Jun 2, 2026
9a435bc
add card
abovedave Jun 2, 2026
1d0ff88
text node adjust
abovedave Jun 2, 2026
e8f41b8
link card with arrow variant
abovedave Jun 3, 2026
4cf2c1a
callout component
abovedave Jun 3, 2026
0ac4249
callout and subtitle
abovedave Jun 3, 2026
75bbc49
fix color name
abovedave Jun 3, 2026
2335fa0
remove unused
abovedave Jun 3, 2026
09d4fdf
newsletter
abovedave Jun 4, 2026
eb23303
add promo style
abovedave Jun 4, 2026
a6794dd
tweaks to inbox preview
abovedave Jun 4, 2026
d07bdeb
dev survey email
abovedave Jun 10, 2026
7324617
prebuild
abovedave Jun 12, 2026
d7b3e97
Merge branch 'main' of https://github.com/StackExchange/Stacks into e…
abovedave Jun 23, 2026
6629451
add email version
abovedave Jun 26, 2026
b9a5443
experimental notice
abovedave Jun 26, 2026
20bb041
allow any template for the endpoint
abovedave Jun 26, 2026
a84c858
Merge branch 'main' of https://github.com/StackExchange/Stacks into e…
abovedave Jun 26, 2026
178f445
new homepage from community-guidelines branch
abovedave Jun 26, 2026
2c1029d
add a title tag
abovedave Jun 26, 2026
18a3484
npm run format
abovedave Jun 26, 2026
96078c5
rebuild with newer vesion of npm
abovedave Jun 26, 2026
ee4744e
tidy unused
abovedave Jun 26, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .prettierignore
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
.vscode/
dist/
**/.svelte-kit
.svelte-kit/
# TODO: prettier breaks less files containing namespaced mixins with whitespaces
# BEFORE PRETTIER: #stacks-internals #responsify('.w25', { width: 25% !important; });
# AFTER PRETTIER: #stacks-internals #responsify('.w25', { width: 25% !important; });;
Expand Down
1,988 changes: 1,441 additions & 547 deletions package-lock.json

Large diffs are not rendered by default.

7 changes: 7 additions & 0 deletions packages/stacks-docs/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,10 @@ The private docs follow the same structure and conventions as public docs. Mark
3. **Add any images or assets** to the same directory as your markdown file

4. **Reference assets** using relative paths (e.g., `./image.svg`) in your markdown

## Email compile API auth (optional)

`POST /api/email/compile` supports an optional shared Bearer token.

- If `STACKS_EMAIL_AUTH_TOKEN` is not set: auth is disabled.
- If `STACKS_EMAIL_AUTH_TOKEN` is set: the request must include `Authorization: Bearer <token>`.
3 changes: 0 additions & 3 deletions packages/stacks-docs/_redirects
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,6 @@
https://alpha.stackoverflow.design/* https://stackoverflow.design/:splat 301
https://beta.stackoverflow.design/* https://stackoverflow.design/:splat 302

# Email section → v2 docs
/email/* https://v2.stackoverflow.design/email/:splat 302

# Redirects from v2 urls
/product /system/develop/using-stacks/ 302
/base/* /system/base/:splat 302
Expand Down
1 change: 1 addition & 0 deletions packages/stacks-docs/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
"dependencies": {
"@docsearch/css": "^4.3.2",
"@docsearch/js": "^4.3.2",
"@stackoverflow/stacks-email": "*",
"@hbsnow/rehype-sectionize": "^1.0.7",
"@stackoverflow/stacks": "*",
"@stackoverflow/stacks-editor": "*",
Expand Down
14 changes: 13 additions & 1 deletion packages/stacks-docs/src/app.css
Original file line number Diff line number Diff line change
Expand Up @@ -307,7 +307,7 @@ body {

.ff-stack-sans-headline,
.ff-stack-sans-headline-notch {
font-family: "Stack Sans Headline";
font-family: "Stack Sans Headline" !important;
}
.ff-stack-sans-headline-notch {
font-feature-settings: "ss01" 1 !important;
Expand Down Expand Up @@ -550,6 +550,18 @@ h1 {
padding: var(--su16);
}

/* Docs section card – used with a thumbnail to link to other areas in the docs i.e, for index pages */

.docs-index-card {
border: var(--su1) solid var(--black-225);
}
.docs-index-card .docs-heading {
margin: 0 var(--su16) var(--su4);
}
.docs-index-card .docs-heading + p.docs-copy {
margin: 0 var(--su16) var(--su16);
}

/* Notices in doc content get breathing room below */
.docs .s-notice {
margin-bottom: var(--su16);
Expand Down
1 change: 1 addition & 0 deletions packages/stacks-docs/src/app.d.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
declare global {
const __APP_VERSION__: string;
const __EMAIL_VERSION__: string;
const __SVELTE_VERSION__: string;

type DocsTocItem = {
Expand Down
94 changes: 94 additions & 0 deletions packages/stacks-docs/src/components/EmailOptionsTable.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
<script lang="ts">
import { onMount } from "svelte";

type ComponentOptionReference = {
argument: string;
type: string;
defaultValue?: string;
renderDefaultValueAsCode?: boolean;
description: string;
};

type EmailCatalogComponent = {
slug: string;
options?: ComponentOptionReference[];
};

type EmailCatalogResponse = {
catalog: {
components: EmailCatalogComponent[];
templates: EmailCatalogComponent[];
};
};

let {
rows = [],
componentSlug,
templateSlug,
}: {
rows?: ComponentOptionReference[];
componentSlug?: string;
templateSlug?: string;
} = $props();

let resolvedRows = $state<ComponentOptionReference[]>([]);

const hasDefaultValue = (value: string | undefined) =>
typeof value === "string" && value.trim().length > 0;

$effect(() => {
if (rows.length > 0) {
resolvedRows = rows;
}
});

onMount(async () => {
if ((!componentSlug && !templateSlug) || resolvedRows.length > 0) {
return;
}

const response = await fetch("/email/compiled/manifest.json");
if (!response.ok) {
return;
}

const manifest = (await response.json()) as EmailCatalogResponse;
const collection = componentSlug
? manifest.catalog.components
: manifest.catalog.templates;
const slug = componentSlug ?? templateSlug;
const match = collection.find((item) => item.slug === slug);
resolvedRows = match?.options ?? [];
});
</script>

<div class="overflow-x-auto mb32">
<table class="docs-table s-table s-table__bx-simple">
<thead>
<tr>
<th class="s-table--cell2" scope="col">Argument</th>
<th class="s-table--cell3" scope="col">Type</th>
<th scope="col">Default</th>
<th scope="col">Description</th>
</tr>
</thead>
<tbody class="fs-caption">
{#each resolvedRows as row (row.argument)}
<tr>
<td><code>{row.argument}</code></td>
<td><code>{row.type}</code></td>
<td>
{#if hasDefaultValue(row.defaultValue)}
{#if row.renderDefaultValueAsCode === false}
{row.defaultValue}
{:else}
<code>{row.defaultValue}</code>
{/if}
{/if}
</td>
<td>{row.description}</td>
</tr>
{/each}
</tbody>
</table>
</div>
Loading
Loading