nextjs SSG + rust web server

Create components for specific hooks

If there are some special hooks were used, for example useSearchParams(), wrap it as a component, using suspense to load it. Ex:

import { Suspense } from 'react';
import ChatComponent from './ChatComponent';

export default function Page() {
 return (
  <div className="font-sans max-w-3xl mx-auto p-5">
    <h1 className="text-2xl font-bold mb-4 text-center">Yidam Chat</h1>
    <Suspense fallback={<div>Loading chat...</div>}>
     <ChatComponent />
    </Suspense>
  </div>
 );
}

Set next.config.ts

import type { NextConfig } from "next";

const nextConfig: NextConfig = {
 /* config options here */
 reactStrictMode: true,
 output: 'export',
 basePath: '/web',
};

export default nextConfig;

Notes

  • Set output: 'export' for npm run build
  • Set basePath: '/web' for the sub-directory of the web root

Set package.json

 "scripts": {
  "dev": "next dev",
  "build": "next build",
  "start": "next start",
  "lint": "next lint"
 },

Notes: just keep as it was

Run command to generate files

npm run build

(Optional) Rust web server setting

use axum::{
  routing::{get, get_service},
  Router,
};

async fn main() {
  let state = Arc::new(AppState {
    context: Mutex::new(Vec::new()),
  });

  let app = Router::new()
  .route("/ws", get(websocket_handler))
  .nest_service("/web", get_service(ServeDir::new("./src/web")))
  .with_state(state);
  const PORT: u16 = 3001;
  // get lan ip
  let listener = tokio::net::TcpListener::bind(format!("0.0.0.0:{}", PORT)).await.unwrap();
  println!("Please open http://{}:{}/web", get_local_ip().unwrap(), PORT);
  axum::serve(listener, app).await.unwrap();
}