Multiple independent lightweight HTML pages for the Doctorina organization, deployed on a single domain.
pages/
├── pages/ # Directory with all pages
│ ├── index/ # Main page (home)
│ │ ├── index.html
│ │ ├── main.ts
│ │ └── style.css
│ ├── tools/ # Utilities page
│ │ ├── index.html
│ │ ├── main.ts
│ │ └── style.css
│ └── ... # Other pages
├── src/
│ └── shared/ # Shared code for all pages
│ ├── utils/ # Utilities (clipboard, validation, etc.)
│ └── styles/ # Shared styles
├── public/ # Static files
├── vite.config.ts # Vite configuration (auto-discovery of pages)
└── package.json
npm installStart dev server (opens main page):
npm run devOpen specific page:
npm run dev:index # Main page
npm run dev:tools # Tools pageOr open in browser:
http://localhost:3000/pages/index/index.htmlhttp://localhost:3000/pages/tools/index.html
npm run build # Build all pages
npm run build:analyze # Build with bundle size analysis
npm run preview # Preview built projectnpm run type-check # TypeScript type checking
npm run lint # Lint code
npm run lint:fix # Auto-fix with linternpm run deploy # Build and deploy to Firebase
npm run deploy:preview # Deploy to preview channel
npm run firebase:serve # Local Firebase hosting test- Create a new directory in the
pages/folder:
mkdir pages/my-new-page- Create page files:
pages/my-new-page/
├── index.html # HTML template
├── main.ts # TypeScript code
└── style.css # Styles (optional)
- index.html - minimal template:
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta content="IE=Edge" http-equiv="X-UA-Compatible" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Doctorina</title>
<meta name="description" content="Doctorina" />
<meta name="theme-color" content="#25D366" />
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.ico" />
<!-- iOS meta tags & icons -->
<meta name="mobile-web-app-capable" content="yes" />
<meta name="apple-mobile-web-app-status-bar-style" content="white" />
<meta name="apple-mobile-web-app-title" content="Doctorina" />
<link rel="apple-touch-icon" href="icons/web-app-manifest-192x192.png" />
</head>
<body>
<div id="app"></div>
<script type="module" src="/pages/my-new-page/main.ts"></script>
</body>
</html>- main.ts - page code:
import { initPage } from "~/shared/utils/page-init";
import "./style.css";
initPage("My New Page - Doctorina");
const app = document.getElementById("app");
if (app) {
app.innerHTML = `
<div class="container">
<h1>My New Page</h1>
<p>Welcome to my new page!</p>
</div>
`;
}- Add npm script (optional) to
package.json:
"dev:my-new-page": "vite --open /pages/my-new-page/index.html"- Done! Vite will automatically discover your page during build.
Ready-to-use utilities are available in src/shared/utils/:
import { initPage } from "~/shared/utils/page-init";
import { copyToClipboard } from "~/shared/utils/clipboard";
import { formatDate, getRelativeTime } from "~/shared/utils/date";
import { isValidEmail, isValidUrl } from "~/shared/utils/validation";
// Initialize page
initPage("Page Title");
// Clipboard operations
await copyToClipboard("Text to copy");
// Date formatting
const formatted = formatDate(new Date());
const relative = getRelativeTime(new Date());
// Validation
if (isValidEmail(email)) {
/* ... */
}
if (isValidUrl(url)) {
/* ... */
}Import shared CSS variables and utilities:
import "~/shared/styles/common.css";Available CSS variables:
var(--primary-color) /* #667eea */
var(--success-color) /* #28a745 */
var(--shadow-lg) /* 0 10px 40px rgba(0,0,0,0.2) */
var(--radius-md) /* 8px */
/* and others... */After npm run build, the dist/ directory will have the following structure:
dist/
├── index.html # Main page
├── tools.html # Tools page
├── assets/ # JS, CSS, and other assets
└── ...
Each page is built independently with minimal dependencies.
Configuration for deploying to pages.doctorina.com.
Initial setup:
npm run firebase:login
npm run firebase:initDeploy:
npm run deploy