Skip to content

Commit 3797d88

Browse files
Initial commit: Graph Technology Developers website
0 parents  commit 3797d88

35 files changed

+6527
-0
lines changed

.eleventy.js

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
import { readFile } from 'node:fs/promises';
2+
import { resolve } from 'node:path';
3+
4+
const passthroughFiles = [
5+
{ from: 'src/assets', to: 'assets' },
6+
{ from: 'src/data/graph.json', to: 'data/graph.json' },
7+
{ from: 'src/css', to: 'css' },
8+
];
9+
10+
/** @param {import('@11ty/eleventy').UserConfig} eleventyConfig */
11+
export default function (eleventyConfig) {
12+
eleventyConfig.setServerOptions({
13+
showAllHosts: true,
14+
});
15+
16+
for (let i = 0; i < passthroughFiles.length; i += 1) {
17+
const entry = passthroughFiles[i];
18+
eleventyConfig.addPassthroughCopy({ [entry.from]: entry.to });
19+
}
20+
21+
eleventyConfig.addWatchTarget('src/css/');
22+
eleventyConfig.addWatchTarget('src/js/');
23+
24+
eleventyConfig.addNunjucksFilter('dateIso', (value) => {
25+
if (!value) {
26+
return '';
27+
}
28+
const date = new Date(value);
29+
if (Number.isNaN(date.getTime())) {
30+
return '';
31+
}
32+
return date.toISOString().split('T')[0];
33+
});
34+
35+
eleventyConfig.addGlobalData('graphData', async () => {
36+
const file = resolve('src/data/graph.json');
37+
const content = await readFile(file, 'utf-8');
38+
return JSON.parse(content);
39+
});
40+
41+
return {
42+
dir: {
43+
input: 'src',
44+
includes: '_includes',
45+
data: '_data',
46+
output: 'dist',
47+
},
48+
templateFormats: ['njk', 'md', '11ty.js'],
49+
htmlTemplateEngine: 'njk',
50+
markdownTemplateEngine: 'njk',
51+
};
52+
}
53+

.github/workflows/pages.yml

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
name: Deploy to GitHub Pages
2+
3+
on:
4+
push:
5+
branches: [main]
6+
workflow_dispatch:
7+
8+
permissions:
9+
contents: read
10+
pages: write
11+
id-token: write
12+
13+
concurrency:
14+
group: pages
15+
cancel-in-progress: true
16+
17+
jobs:
18+
build:
19+
runs-on: ubuntu-latest
20+
steps:
21+
- name: Checkout
22+
uses: actions/checkout@v4
23+
24+
- name: Setup Node.js
25+
uses: actions/setup-node@v4
26+
with:
27+
node-version: '22'
28+
cache: npm
29+
30+
- name: Install dependencies
31+
run: npm ci
32+
33+
- name: Build
34+
run: npm run build
35+
36+
- name: Upload artifact
37+
uses: actions/upload-pages-artifact@v3
38+
with:
39+
path: dist
40+
41+
deploy:
42+
needs: build
43+
runs-on: ubuntu-latest
44+
environment:
45+
name: github-pages
46+
url: ${{ steps.deployment.outputs.page_url }}
47+
steps:
48+
- name: Deploy to GitHub Pages
49+
id: deployment
50+
uses: actions/deploy-pages@v4
51+

.gitignore

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
node_modules/
2+
dist/
3+
.11tycache/
4+
.cache/
5+
.DS_Store
6+
7+

CNAME

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
graphtech.dev
2+

README.md

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
# Graph Technology Developers — Hub
2+
3+
Static site powered by Eleventy (11ty), TypeScript (esbuild), and D3.js. The site delivers an SEO-friendly hub with a progressively-enhanced graph navigation experience.
4+
5+
## Prerequisites
6+
7+
- Node.js 22+
8+
- npm 10+
9+
10+
## Setup
11+
12+
```sh
13+
npm install
14+
```
15+
16+
## Development
17+
18+
```sh
19+
npm run dev
20+
```
21+
22+
- Runs esbuild in watch mode and Eleventy dev server at `http://localhost:8080`.
23+
- Source directories live in `src/`.
24+
25+
## Build
26+
27+
```sh
28+
npm run build
29+
```
30+
31+
- Outputs static site to `dist/` for deployment.
32+
33+
Preview the built site locally:
34+
35+
```sh
36+
npm run preview
37+
```
38+
39+
## Editing Content
40+
41+
- Homepage: `src/index.njk`
42+
- Markdown pages: `src/content/*.md`
43+
- Graph data: `src/data/graph.json`
44+
- CSS: `src/css/base.css`, `src/css/graph.css`
45+
- Scripts: `src/js/*.ts`
46+
47+
### Adding Nodes or Links
48+
49+
Edit `src/data/graph.json`:
50+
51+
```json
52+
{
53+
"nodes": [
54+
{
55+
"id": "unique-id",
56+
"label": "Name",
57+
"type": "topic",
58+
"href": "/path/",
59+
"description": "Short description.",
60+
"tags": ["tag1", "tag2"],
61+
"pinned": false
62+
}
63+
],
64+
"links": [
65+
{ "source": "hub", "target": "unique-id", "kind": "relates" }
66+
]
67+
}
68+
```
69+
70+
After updates, run `npm run build` to regenerate the site.
71+
72+
## Deployment
73+
74+
- GitHub Pages via `.github/workflows/pages.yml`
75+
- Custom domain `graphtech.dev` configured via `CNAME`
76+
77+
Push to `main` to trigger the Pages workflow.
78+
79+
## Testing & Performance
80+
81+
- Run Lighthouse against `dist/` or deployed site (target ≥ 90 mobile Perf/Accessibility).
82+
- JS bundle budget: ≤ 200KB gzipped (D3 + modules bundled via esbuild).
83+
- Prefers-reduced-motion respected by graph interactions.
84+
85+
## Analytics
86+
87+
- Plausible (`data-domain="graphtech.dev"`) collects page views and custom events (`graph_node_hover`, `graph_node_click`, `graph_filter_used`).
88+
89+
## License
90+
91+
MIT
92+
93+
747 KB
Loading

esbuild.config.mjs

Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
import { build, context } from 'esbuild';
2+
import { mkdir, rm, writeFile } from 'node:fs/promises';
3+
import { resolve } from 'node:path';
4+
5+
const watch = process.argv.includes('--watch');
6+
7+
const outdir = resolve('dist/assets/js');
8+
9+
async function prepareOutDir() {
10+
await rm(outdir, { recursive: true, force: true });
11+
await mkdir(outdir, { recursive: true });
12+
}
13+
14+
const baseConfig = {
15+
entryPoints: ['src/js/graph.ts', 'src/js/search.ts', 'src/js/analytics.ts'],
16+
outdir,
17+
bundle: true,
18+
sourcemap: true,
19+
format: 'esm',
20+
target: ['es2022'],
21+
splitting: true,
22+
chunkNames: 'chunks/[name]-[hash]',
23+
metafile: true,
24+
loader: {
25+
'.json': 'json',
26+
},
27+
define: {
28+
'process.env.NODE_ENV': JSON.stringify(watch ? 'development' : 'production'),
29+
},
30+
minify: !watch,
31+
};
32+
33+
async function writeMetaFile(metafile) {
34+
const metaPath = resolve(outdir, 'meta.json');
35+
await writeFile(metaPath, JSON.stringify(metafile, null, 2), 'utf-8');
36+
}
37+
38+
async function runBuild() {
39+
await prepareOutDir();
40+
41+
if (watch) {
42+
const ctx = await context(baseConfig);
43+
await ctx.watch();
44+
console.log('🔁 esbuild is watching for changes');
45+
} else {
46+
const result = await build({
47+
entryPoints: ['src/js/graph.ts', 'src/js/search.ts', 'src/js/analytics.ts', 'src/js/glitch.ts'],
48+
outdir,
49+
bundle: true,
50+
sourcemap: true,
51+
format: 'esm',
52+
target: ['es2022'],
53+
splitting: true,
54+
chunkNames: 'chunks/[name]-[hash]',
55+
metafile: true,
56+
loader: {
57+
'.json': 'json',
58+
},
59+
define: {
60+
'process.env.NODE_ENV': JSON.stringify(watch ? 'development' : 'production'),
61+
},
62+
minify: !watch,
63+
});
64+
await writeMetaFile(result.metafile);
65+
console.log('✅ esbuild build complete');
66+
}
67+
}
68+
69+
runBuild().catch((error) => {
70+
console.error(error);
71+
process.exit(1);
72+
});
73+

0 commit comments

Comments
 (0)