Skip to content

Commit a1584c5

Browse files
committed
rework variable replacement logic
We now do it at built time, using remark and rehype plugins.
1 parent 11656c4 commit a1584c5

File tree

8 files changed

+77
-102
lines changed

8 files changed

+77
-102
lines changed

packages/astro-theme/index.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import tailwind from "@astrojs/tailwind";
44
import robotsTxt from "astro-robots-txt";
55
import publicDir from "astro-public";
66
import pagefind from "./pagefind";
7+
import { remarkReplaceVars, rehypeReplaceVars } from "./replace-variables";
78
import svelte from "@astrojs/svelte";
89
import astroExpressiveCode, { loadShikiTheme } from "astro-expressive-code";
910
import remarkObsidianCallout from "remark-obsidian-callout";
@@ -57,7 +58,9 @@ export default function ThemeIntegration(
5758
frames: {},
5859
},
5960
}),
60-
mdx(),
61+
mdx({
62+
remarkPlugins: [ remarkReplaceVars ],
63+
}),
6164
sitemap(),
6265
tailwind(),
6366
robotsTxt(),
@@ -98,8 +101,9 @@ export default function ThemeIntegration(
98101
});
99102
params.updateConfig({
100103
markdown: {
101-
remarkPlugins: [[remarkObsidianCallout, {}]],
104+
remarkPlugins: [[remarkObsidianCallout, {}], remarkReplaceVars ],
102105
rehypePlugins: [
106+
rehypeReplaceVars,
103107
rehypeSlug, // astro does this automatically but rehype-autolink-headings needs it
104108
[
105109
rehypeAutolinkHeadings,

packages/astro-theme/layouts/DocsArticle.astro

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -176,5 +176,4 @@ function getEditHref(id: string): string {
176176

177177
import "../lib/callout";
178178
import "../lib/terminal-os-tabs";
179-
import "../lib/code-replace";
180179
</script>

packages/astro-theme/lib/code-replace.js

Lines changed: 0 additions & 41 deletions
This file was deleted.

packages/astro-theme/package.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@
5353
"rehype-autolink-headings": "^7.0.0",
5454
"rehype-external-links": "^3.0.0",
5555
"rehype-slug": "^6.0.0",
56-
"remark-obsidian-callout": "^1.1.3"
56+
"remark-obsidian-callout": "^1.1.3",
57+
"unist-util-visit": "^5.0.0"
5758
},
5859
"devDependencies": {
5960
"sirv": "^2.0.4"
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import { visit } from 'unist-util-visit';
2+
3+
const replacements = {
4+
CX_LATEST: "1.1.5",
5+
BP_LATEST: "1.0",
6+
};
7+
8+
export function remarkReplaceVars() {
9+
return (tree) => {
10+
visit(tree, ['text', 'code', 'inlineCode'], (node) => {
11+
if (node.value) {
12+
Object.entries(replacements).forEach(([key, value]) => {
13+
node.value = node.value.replaceAll(`%${key}%`, value);
14+
});
15+
}
16+
});
17+
};
18+
}
19+
export function rehypeReplaceVars() {
20+
return (tree) => {
21+
visit(tree, 'element', (node) => {
22+
if (node.properties) {
23+
Object.entries(node.properties).forEach(([prop, val]) => {
24+
if (typeof val === 'string') {
25+
Object.entries(replacements).forEach(([key, value]) => {
26+
node.properties[prop] = val.replaceAll(`%${key}%`, value);
27+
});
28+
}
29+
});
30+
}
31+
});
32+
visit(tree, 'mdxJsxFlowElement', (node) => {
33+
if (node.attributes) {
34+
Object.entries(node.attributes).forEach(([idx, attr]) => {
35+
if (typeof attr.value === 'string') {
36+
Object.entries(replacements).forEach(([key, value]) => {
37+
attr.value = attr.value.replaceAll(`%${key}%`, value);
38+
});
39+
}
40+
});
41+
}
42+
});
43+
visit(tree, 'text', (node) => {
44+
Object.entries(replacements).forEach(([key, value]) => {
45+
node.value = node.value.replaceAll(`%${key}%`, value);
46+
});
47+
});
48+
};
49+
}
50+

pnpm-lock.yaml

Lines changed: 11 additions & 13 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

sites/browserpod/src/content/docs/00-overview.mdx

Lines changed: 7 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ description: Run Dev Environments in your browser
77
import LinkButton from "@leaningtech/astro-theme/components/LinkButton.astro";
88
import { DISCORD_URL } from "@/consts.ts";
99

10+
<div class="%BP_LATEST%"
11+
/>
1012
<div class="not-prose flex gap-2 mb-2">
1113
<img
12-
src="https://img.shields.io/badge/version-0.1-orange"
13-
alt="Version 0.1"
14+
src="https://img.shields.io/badge/version-%BP_LATEST%-orange"
15+
alt="Version %BP_LATEST%"
1416
/>
1517
<a href="https://discord.leaningtech.com/">
1618
<img
@@ -27,7 +29,7 @@ import { DISCORD_URL } from "@/consts.ts";
2729
</div>
2830

2931
<div class="text-lg">
30-
Instant, in-browser runtime for Node.js, Python, and Ruby on Rails to power the future of Web-based developer experiences.
32+
Instant, in-browser runtime for Node.js, Python, and Ruby on Rails to power the future of Web-based developer experiences.
3133

3234
Run Node.js projects in your browser, unmodified (Python, Ruby, and more coming in the future).
3335

@@ -43,7 +45,7 @@ See it in action in our [SvelteKit+Vite demo](https://vitedemo.browserpod.io)
4345
</div>
4446

4547
```html
46-
<script src="https://rt.browserpod.io/20251014_102/browserpod.js"></script>
48+
<script src="https://rt.browserpod.io/%BP_LATEST%/browserpod.js"></script>
4749
```
4850

4951
## Use Cases
@@ -64,45 +66,7 @@ Let AI assistants and Agents run loose on your project, but isolated from the re
6466

6567
BrowserPod has a simple yet powerful [API](/docs/reference).
6668

67-
You can get up an running with few simple steps.
68-
69-
First, you need to boot your pod:
70-
71-
```js
72-
const pod = await BrowserPod.boot({ apiKey: "...", nodeVersion: "22" /*...*/ });
73-
```
74-
75-
Then, you need to add your project's files to the pod. Currently, you need to fetch the contents yourself, and re-create the directory structure inside the pod's filesystem. We will add more convenient setup methods in the future:
76-
77-
```js
78-
await pod.createDirectory("/project");
79-
for await (const f of myfiles) {
80-
const response = await fetch(f.url);
81-
const buffer = await response.arrayBuffer();
82-
const fd = await pod.createFile(f.path);
83-
fd.write(buffer);
84-
fd.close();
85-
}
86-
```
87-
88-
Then, run any setup step required to initialize your project:
89-
90-
```js
91-
await pod.run("npm", ["install"], { cwd: "/project" });
92-
```
93-
94-
And finally, run the dev server (or whatever workload your project provides):
95-
96-
```js
97-
await pod.run("npm", ["run", "dev"], { cwd: "/project" });
98-
```
99-
100-
Listening ports are associated with a Portal, which you can embed in the page with an IFrame, or visit from another Tab, or even another device, anywhere in the World.
101-
To get notified when a portal is created, do:
102-
103-
```js
104-
pod.onPortal(({url, port} => { /*...load iframe...*/ });
105-
```
69+
You can get up an running with few simple steps by following our [Quickstart](/docs/getting-started) page.
10670

10771
## How does BrowserPod work?
10872

sites/browserpod/src/content/docs/10-getting-started/index.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ title: Quickstart
33
description: Getting started with BrowserPod
44
---
55

6-
## What BrowserPod Does
6+
## What BrowserPod Does %BP_LATEST%
77

88
**BrowserPod is a technology for running node.js environments entirely client-side.**
99

0 commit comments

Comments
 (0)