This guide shows how to integrate the external examples repository with the main ExoQuery website.
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β ExoQuery Website β
β β
β ββββββββββββββββββββ ββββββββββββββββββββββββ β
β β Built-in β β External Examples β β
β β Examples β β (Dynamic Loading) β β
β β (examples.md) β β β β
β ββββββββββββββββββββ ββββββββββββββββββββββββ β
β β β β
β β β β
β βΌ βΌ β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
β β Example Display Component β β
β β β’ Checks if slug exists in built-in examples β β
β β β’ Falls back to loading from external repo β β
β β β’ Caches external examples in localStorage β β
β ββββββββββββββββββββββββββββββββββββββββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β
β Fetches from
βΌ
ββββββββββββββββββββββββββββββββββββββββββββ
β External Examples Repository β
β β
β GitHub Pages / jsDelivr CDN β
β β’ manifest.json β
β β’ examples/*.json β
ββββββββββββββββββββββββββββββββββββββββββββ
The utility file has been created at:
exoquery-site/src/utils/loadExternalExamples.ts
Modify src/components/HeroSection.astro to support dynamic loading:
---
import CodePlayground from './CodePlayground.vue';
import HeroCodeLoader from './HeroCodeLoader.vue';
// Default example (fallback)
const defaultHeroCode = `...`;
---
<section class="hero" id="home">
<div class="hero-content">
<h1>Stop Writing 300 Queries<br/>When You Need 30</h1>
<p class="subtitle">The only Kotlin library with true query composition.</p>
<!-- Use new loader component that handles ?example= query param -->
<HeroCodeLoader
client:only="vue"
:defaultCode="defaultHeroCode"
:defaultSqlOutput="heroSqlOutput"
:defaultSchema="heroCodeSchema"
/>
</div>
</section>Create src/components/HeroCodeLoader.vue:
<template>
<CodePlayground
:code="currentCode"
:initial-sql-code="currentSqlOutput"
:schema="currentSchema"
/>
</template>
<script setup lang="ts">
import { ref, onMounted } from 'vue';
import CodePlayground from './CodePlayground.vue';
import { loadExternalExample } from '../utils/loadExternalExamples';
interface Props {
defaultCode: string;
defaultSqlOutput: string;
defaultSchema: string;
}
const props = defineProps<Props>();
const currentCode = ref(props.defaultCode);
const currentSqlOutput = ref(props.defaultSqlOutput);
const currentSchema = ref(props.defaultSchema);
async function loadExampleFromUrl() {
if (typeof window === 'undefined') return;
const params = new URLSearchParams(window.location.search);
const exampleSlug = params.get('example');
if (!exampleSlug) return;
console.log(`Loading external example: ${exampleSlug}`);
const example = await loadExternalExample(exampleSlug);
if (example) {
currentCode.value = example.code;
currentSqlOutput.value = example.output;
currentSchema.value = example.schema || '';
console.log(`Loaded external example: ${example.title}`);
} else {
console.warn(`Failed to load external example: ${exampleSlug}`);
}
}
onMounted(() => {
loadExampleFromUrl();
// Listen for URL changes
window.addEventListener('popstate', loadExampleFromUrl);
});
</script>To show external examples in the examples browser, update Examples.vue:
import { ref, onMounted, computed } from 'vue';
import examplesContent from '../content/examples.md?raw';
import { parseExamples, type Example } from '../utils/parseExamples';
import { getAllExternalExamples } from '../utils/loadExternalExamples';
// Parse built-in examples
const builtInExamples: Example[] = parseExamples(examplesContent);
const externalExamples = ref<Example[]>([]);
// Combine both
const examples = computed(() => [...builtInExamples, ...externalExamples.value]);
onMounted(async () => {
// Load external examples metadata
const external = await getAllExternalExamples();
if (external) {
// Convert manifest entries to Example format
externalExamples.value = Object.entries(external).map(([slug, meta]) => ({
slug,
title: meta.title,
description: meta.description,
category: meta.category,
icon: meta.icon,
code: '', // Will be loaded on demand
output: '',
}));
}
});Run the setup script:
cd exoquery-examples-web
./setup-local-dev.shThis will:
- Build the examples
- Create a symlink in
exoquery-site/public/examples-local - Create
.env.developmentif needed
- Build examples:
cd exoquery-examples-web
npm run build- Create symlink:
cd exoquery-site/public
ln -s ../../exoquery-examples-web/dist examples-local- The site will now use local examples in dev mode
Start the site:
cd exoquery-site
npm run devTest URLs:
- Built-in example:
http://localhost:4321/examples/basic-select - External example:
http://localhost:4321/#home?example=window-functions
In src/utils/loadExternalExamples.ts, update the GitHub username:
const EXTERNAL_EXAMPLES_CONFIG = {
baseUrl: import.meta.env.DEV
? '/examples-local'
: 'https://cdn.jsdelivr.net/gh/YOUR_USERNAME/exoquery-examples-web@main/dist',
// ...
};In the exoquery-examples-web repository:
- Go to Settings β Pages
- Source: "GitHub Actions"
- Push to
mainto trigger deployment
After ~2 minutes:
- Check manifest:
https://YOUR_USERNAME.github.io/exoquery-examples-web/manifest.json - Check example:
https://YOUR_USERNAME.github.io/exoquery-examples-web/examples/window-functions.json
https://exoquery.io/examples/basic-select
https://exoquery.io/examples/complex-joins
https://exoquery.io/#home?example=window-functions
https://exoquery.io/#home?example=advanced-subqueries
Users can share direct links:
https://exoquery.io/#home?example=recursive-cte
- Check symlink exists:
ls -la exoquery-site/public/examples-local - Rebuild examples:
cd exoquery-examples-web && npm run build - Clear cache: Open DevTools β Application β Local Storage β Clear
- Verify GitHub Pages is enabled
- Check GitHub Actions completed successfully
- Wait 2-5 minutes for CDN propagation
- Try force refresh: Add
?v=timestampto URL
- GitHub Pages: β CORS enabled by default
- jsDelivr: β CORS enabled by default
- Custom domain: May need CORS headers
- β More examples without site updates
- β Shareable direct links
- β Fast loading (CDN + caching)
- β Add examples without site rebuild
- β Rapid local iteration
- β Version controlled examples
- β TypeScript type safety
- β Separate concerns (site vs content)
- β Independent deployment
- β Easy rollback (Git tags)
See src/utils/loadExternalExamples.ts for:
loadExternalExample(slug)- Load single exampleloadExternalManifest()- Get all available examplesisExternalExample(slug)- Check if example existsclearExternalCache()- Clear localStorage cache