Personal Website with Server-Side Active Navigation

Create a personal portfolio website with multiple pages and server-side active navigation using an HTTP Val.

iamseeley/multirouteHTML
import { websiteStyles } from "https://esm.town/v/iamseeley/websiteStyles";
import { personalData } from "https://esm.town/v/iamseeley/personalData";
import { generateTrackingHtml } from 'https://esm.town/v/iamseeley/counterTown';

export default async function (req: Request): Promise<Response> {
  const url = new URL(req.url);
  const path = url.pathname;
Function to create navigation links with active state
iamseeley/multirouteHTML
  function createNavLinks(currentPath: string): string {
    const links = [
      { path: '/', text: 'Home' },
      { path: '/about', text: 'About' },
      { path: '/projects', text: 'Projects' }
    ];

    return links.map(link =>
      `<a href="${link.path}" class="${currentPath === link.path ? 'active' : ''}">${link.text}</a>`
    ).join('');
  }

    const trackingHtmlResponse = generateTrackingHtml(req);
    const trackingHtml = await trackingHtmlResponse.text();
Common HTML structure
iamseeley/multirouteHTML
  function createHTML(title: string, content: string, req: Request): string {
    return `
      <!DOCTYPE html>
      <html lang="en">
      <head>
        <meta charset="UTF-8">
        <meta name="viewport" content="width=device-width, initial-scale=1.0">
        <title>${personalData.name} | HTML as String</title>
        <style>
          ${websiteStyles}
        </style>
      </head>
      <body>
        <header>
          <h1>${personalData.name}</h1>
          <p>${personalData.label}</p>
        </header>
        <nav>
          ${createNavLinks(path)}
        </nav>
        <main>
          ${content}
        </main>
        <footer>
          <ul>
            ${personalData.profiles.map((profile, index) => `
              <li key={${index}}>
                <a href='${profile.url}' target="_blank" rel="noopener noreferrer">
                  ${profile.network}
                </a>
              </li>
            `).join('')}
          </ul>
        </footer>
        ${trackingHtml}
      </body>
      </html>
    `;
  }
Router function to handle different routes
iamseeley/multirouteHTML
  function router(path: string, req: Request): Response {
    switch (path) {
      case '/':
        return homePage(req);
      case '/about':
        return aboutPage(req);
      case '/projects':
        return projectsPage(req);
      default:
        return notFoundPage(req);
    }
  }
Home page
iamseeley/multirouteHTML
  function homePage(req: Request): Response {
    const content = `
      <h2>Welcome to My Portfolio</h2>
      <p>${personalData.summary}</p>
      <p><strong>This website is rendered server-side with pure HTML.</strong></p>
      <p>Check out the <a href='https://www.val.town/v/iamseeley/multirouteHTML'>source</a> and start building your own site!</p>
  
    `;
    return new Response(createHTML("Home", content, req), {
      headers: { "Content-Type": "text/html" },
    });
  }
About page
iamseeley/multirouteHTML
  function aboutPage(req: Request): Response {
    const content = `
      <h2>About Me</h2>
      <p>${personalData.about}</p>
    `;
    return new Response(createHTML("About", content, req), {
      headers: { "Content-Type": "text/html" },
    });
  }
Projects page
iamseeley/multirouteHTML
  function projectsPage(req: Request): Response {
    const content = `
      <h2>My Projects</h2>
      ${personalData.projects.map(project => `
        <a href="${project.url}" target="_blank" class="projectLink">
          <div class="project">
            <h3>${project.name}</h3>
            <p>${project.description}</p>
          </div>
        </a>
      `).join('')}
    `;
    return new Response(createHTML("Projects", content, req), {
      headers: { "Content-Type": "text/html" },
    });
  }
404 Not Found page
iamseeley/multirouteHTML
  function notFoundPage(req: Request): Response {
    const content = `
      <h2>404 Not Found</h2>
      <p>Sorry, the page you're looking for doesn't exist.</p>
      <p><a href="/">Return to Home</a></p>
    `;
    return new Response(createHTML("404 Not Found", content, req), {
      status: 404,
      headers: { "Content-Type": "text/html" },
    });
  }
Use the router to handle the request
iamseeley/multirouteHTML
  return router(path, req);
}