feat: configure basePath from env and update font strategy

This commit is contained in:
2026-05-16 10:02:11 +07:00
parent 1a13083fc5
commit e652279b41
7 changed files with 74 additions and 21 deletions
+2 -1
View File
@@ -1,3 +1,4 @@
PORT=3000
# MongoDB — summit request queue (registration + feedback)
MONGODB_URI=mongodb://localhost:27017/ipv6_summit
MONGODB_URI=mongodb://localhost:27017/ipv6_summit
NEXT_PUBLIC_BASE_PATH=/ipv6
+1 -8
View File
@@ -1,7 +1,5 @@
"use client";
import { useEffect, useState } from "react";
// Tên file chính xác trong public/assets/img/carousel/
const ROW_1 = [
{ name: "NVIDIA", file: "Nvidia_logo.svg.png" },
@@ -76,12 +74,7 @@ function CarouselRow({
}
export default function PartnersCarousel() {
const [base, setBase] = useState("");
useEffect(() => {
const match = window.location.pathname.match(/^(\/ipv6)/);
setBase(match ? match[1] : "");
}, []);
const base = process.env.NEXT_PUBLIC_BASE_PATH || "";
return (
<section className="w-full py-16 lg:py-24 overflow-hidden border-t border-white/5">
+7 -9
View File
@@ -1,12 +1,6 @@
@import "tailwindcss";
@font-face {
font-family: "Nasalization";
src: url("/assets/webfonts/Nasalization Rg.otf") format("opentype");
font-weight: normal;
font-style: normal;
font-display: swap;
}
/* @font-face Nasalization được inject qua layout.tsx để hỗ trợ basePath động */
@theme {
/* IPV6 Summit design tokens */
@@ -24,7 +18,7 @@
--color-on-surface-variant: #e0e0e0;
--color-outline: #c5a059;
--font-body-base: "Nasalization", system-ui, sans-serif;
--font-body-base: "Roboto", system-ui, sans-serif;
--font-display-lg: "Nasalization", system-ui, sans-serif;
--font-label-caps: "Nasalization", system-ui, sans-serif;
--font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono",
@@ -45,10 +39,14 @@ html {
body {
background-color: var(--color-background);
color: var(--color-on-surface-variant);
font-family: "Nasalization", system-ui, sans-serif;
font-family: "Roboto", system-ui, sans-serif;
overflow-x: hidden;
}
h1, h2, h3, h4, h5, h6 {
font-family: "Nasalization", system-ui, sans-serif;
}
input::placeholder,
textarea::placeholder {
color: rgba(224, 224, 224, 0.4);
+14 -1
View File
@@ -3,6 +3,8 @@ import "../public/assets/css/all.min.css";
import "./globals.css";
import { LanguageProvider } from "@/app/context/LanguageContext";
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
export const metadata: Metadata = {
metadataBase: new URL(process.env.NEXT_PUBLIC_BASE_URL || "http://localhost:3000"),
title: "IPv6 Summit 2026 | Infrastructure for AI",
@@ -14,14 +16,25 @@ export default function RootLayout({ children }: { children: React.ReactNode })
return (
<html lang="en">
<head>
{/* Nasalization font — path prefixed with basePath for subdirectory deployments */}
<style dangerouslySetInnerHTML={{ __html: `
@font-face {
font-family: "Nasalization";
src: url("${basePath}/assets/webfonts/Nasalization Rg.otf") format("opentype");
font-weight: normal;
font-style: normal;
font-display: swap;
}
`}} />
{/* Fonts */}
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link
href="https://fonts.googleapis.com/css2?family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Geist:wght@400;600&family=JetBrains+Mono:wght@400;500&display=swap"
href="https://fonts.googleapis.com/css2?family=Roboto:wght@300;400;500;700&family=Space+Grotesk:wght@300;400;500;600;700&family=Inter:wght@300;400;500;600;700&family=Geist:wght@400;600&family=JetBrains+Mono:wght@400;500&display=swap"
rel="stylesheet"
/>
{/* Icons */}
<link rel="icon" href={`${basePath}/assets/img/tech-logo.png`} type="image/png" />
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css"
+4 -2
View File
@@ -1,15 +1,17 @@
import type { NextConfig } from "next";
const basePath = process.env.NEXT_PUBLIC_BASE_PATH || "";
const nextConfig: NextConfig = {
/* config options here */
basePath: '/ipv6',
basePath,
trailingSlash: true,
output: "standalone",
async redirects() {
return [
{
source: "/",
destination: "/ipv6",
destination: basePath || "/",
basePath: false,
permanent: false,
},
+46
View File
@@ -20,6 +20,7 @@
"@types/react": "^19",
"@types/react-dom": "^19",
"dotenv": "^17.4.2",
"dotenv-cli": "11.0.0",
"eslint": "^9",
"eslint-config-next": "16.1.6",
"sass": "^1.98.0",
@@ -3690,6 +3691,51 @@
"url": "https://dotenvx.com"
}
},
"node_modules/dotenv-cli": {
"version": "11.0.0",
"resolved": "https://registry.npmjs.org/dotenv-cli/-/dotenv-cli-11.0.0.tgz",
"integrity": "sha512-r5pA8idbk7GFWuHEU7trSTflWcdBpQEK+Aw17UrSHjS6CReuhrrPcyC3zcQBPQvhArRHnBo/h6eLH1fkCvNlww==",
"dev": true,
"license": "MIT",
"dependencies": {
"cross-spawn": "^7.0.6",
"dotenv": "^17.1.0",
"dotenv-expand": "^12.0.0",
"minimist": "^1.2.6"
},
"bin": {
"dotenv": "cli.js"
}
},
"node_modules/dotenv-expand": {
"version": "12.0.3",
"resolved": "https://registry.npmjs.org/dotenv-expand/-/dotenv-expand-12.0.3.tgz",
"integrity": "sha512-uc47g4b+4k/M/SeaW1y4OApx+mtLWl92l5LMPP0GNXctZqELk+YGgOPIIC5elYmUH4OuoK3JLhuRUYegeySiFA==",
"dev": true,
"license": "BSD-2-Clause",
"dependencies": {
"dotenv": "^16.4.5"
},
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/dotenv-expand/node_modules/dotenv": {
"version": "16.6.1",
"resolved": "https://registry.npmjs.org/dotenv/-/dotenv-16.6.1.tgz",
"integrity": "sha512-uBq4egWHTcTt33a72vpSG0z3HnPuIl6NqYcTrKEg2azoEyl2hpW0zqlxysq2pK9HlDIHyHyakeYaYnSAwd8bow==",
"dev": true,
"license": "BSD-2-Clause",
"engines": {
"node": ">=12"
},
"funding": {
"url": "https://dotenvx.com"
}
},
"node_modules/dunder-proto": {
"version": "1.0.1",
"resolved": "https://registry.npmjs.org/dunder-proto/-/dunder-proto-1.0.1.tgz",
Binary file not shown.

After

Width:  |  Height:  |  Size: 115 KiB