Skip to content

Commit

Permalink
feat: ssg
Browse files Browse the repository at this point in the history
  • Loading branch information
Fyko committed Oct 27, 2023
1 parent 968f469 commit 908fb17
Show file tree
Hide file tree
Showing 4 changed files with 101 additions and 0 deletions.
34 changes: 34 additions & 0 deletions web/prerender.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Pre-render the app into static HTML.
// run `yarn generate` and then `dist/static` can be served as a static site.

import fs from 'node:fs';
import path from 'node:path';
import { fileURLToPath } from 'node:url';

const __dirname = path.dirname(fileURLToPath(import.meta.url));
const toAbsolute = (p) => path.resolve(__dirname, p);

const template = fs.readFileSync(toAbsolute('dist/static/index.html'), 'utf-8');
const { render } = await import('./dist/server/entry-server.js');

// determine routes to pre-render from src/pages
const routesToPrerender = fs
.readdirSync(toAbsolute('src/pages'))
.map((file) => {
const name = file.replace(/\.tsx$/, '').toLowerCase()
return name === 'home' ? `/` : `/${name}`
});

(async () => {
// pre-render each route...
for (const url of routesToPrerender) {
const context = {}
const appHtml = await render(url, context)

const html = template.replace(`<!--app-html-->`, appHtml)

const filePath = `dist/static${url === '/' ? '/index' : url}.html`
fs.writeFileSync(toAbsolute(filePath), html)
console.log('pre-rendered:', filePath)
}
})();
18 changes: 18 additions & 0 deletions web/src/entry-client.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import {enableReactTracking} from '@legendapp/state/config/enableReactTracking';
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.tsx';
import './index.css';
import { BrowserRouter } from 'react-router-dom';

enableReactTracking({
auto: true,
});

ReactDOM.hydrateRoot(
document.getElementById('app')!,
<BrowserRouter>
<App />
</BrowserRouter>,
)
console.log('hydrated')
11 changes: 11 additions & 0 deletions web/src/entry-server.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import ReactDOMServer from 'react-dom/server'
import { StaticRouter } from 'react-router-dom/server'
import App from './App.tsx';

export function render(url: string) {
return ReactDOMServer.renderToString(
<StaticRouter location={url} >
<App />
</StaticRouter>,
)
}
38 changes: 38 additions & 0 deletions web/src/pages/Home.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import {CrateHit, fetchCrateCount} from '../util/meili';
import {ObservableObject} from '@legendapp/state';
import {useObservable} from '@legendapp/state/react';
import {performSearch} from '../util/search';
import {Header} from '../components/Header';
import {Main} from '../components/Main';

export type InnerAppState = {
hits: CrateHit[];
count: number;
requestTime: string;
};

export type AppState = ObservableObject<InnerAppState>;

export function Home() {
const state$ = useObservable<InnerAppState>({
hits: [],
requestTime: '',
count: 0,
});
performSearch(state$, '');
fetchCrateCount(state$);

return (
<>
<Header state$={state$} />
<Main state$={state$} />
<footer>
<div className="inner-col">
<p>
Forked from <a href="https://github.com/meilisearch/demos">Meilisearch Demos</a>.
</p>
</div>
</footer>
</>
);
}

0 comments on commit 908fb17

Please sign in to comment.