From 3aef4dda377979e1d4d7b4d785551e2a615bf82a Mon Sep 17 00:00:00 2001 From: Tushar <80577646+TusharThakur04@users.noreply.github.com> Date: Fri, 19 Jun 2026 13:09:29 +0530 Subject: [PATCH 1/3] feat: add home page --- assets/icon.svg | 1 + .../HomePage/ConfigSection/ConfigSection.jsx | 184 ++++++++++++++++ .../HomePage/ConfigSection/index.module.css | 197 ++++++++++++++++++ .../FeaturesSection/FeaturesSection.jsx | 151 ++++++++++++++ .../HomePage/FeaturesSection/index.module.css | 110 ++++++++++ components/HomePage/Hero/Hero.jsx | 94 +++++++++ components/HomePage/Hero/index.module.css | 194 +++++++++++++++++ components/HomePage/TrustedBy/TrustedBy.jsx | 28 +++ .../HomePage/TrustedBy/index.module.css | 55 +++++ layouts/Home/index.jsx | 21 +- package-lock.json | 193 ++++++++++++++--- package.json | 1 + 12 files changed, 1198 insertions(+), 31 deletions(-) create mode 100644 assets/icon.svg create mode 100644 components/HomePage/ConfigSection/ConfigSection.jsx create mode 100644 components/HomePage/ConfigSection/index.module.css create mode 100644 components/HomePage/FeaturesSection/FeaturesSection.jsx create mode 100644 components/HomePage/FeaturesSection/index.module.css create mode 100644 components/HomePage/Hero/Hero.jsx create mode 100644 components/HomePage/Hero/index.module.css create mode 100644 components/HomePage/TrustedBy/TrustedBy.jsx create mode 100644 components/HomePage/TrustedBy/index.module.css diff --git a/assets/icon.svg b/assets/icon.svg new file mode 100644 index 00000000..8f7eaa52 --- /dev/null +++ b/assets/icon.svg @@ -0,0 +1 @@ +icon \ No newline at end of file diff --git a/components/HomePage/ConfigSection/ConfigSection.jsx b/components/HomePage/ConfigSection/ConfigSection.jsx new file mode 100644 index 00000000..acf06247 --- /dev/null +++ b/components/HomePage/ConfigSection/ConfigSection.jsx @@ -0,0 +1,184 @@ +import { useState } from 'react'; + +import styles from './index.module.css'; + +import { Prism as SyntaxHighlighter } from 'react-syntax-highlighter'; +import { vscDarkPlus } from 'react-syntax-highlighter/dist/esm/styles/prism'; + +export default function ConfigSection() { + const [activeSyntax, setActiveSyntax] = useState('js'); + + const jsCode = `// webpack.config.js + const path = require('path'); + + module.exports = { + entry: './src/index.js', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist') + }, + mode: 'production' + };`; + + const mjsCode = `// webpack.config.mjs + import path from 'path'; + import { fileURLToPath } from 'url'; + + const __dirname = path.dirname(fileURLToPath(import.meta.url)); + + export default { + entry: './src/index.js', + output: { + filename: 'bundle.js', + path: path.resolve(__dirname, 'dist') + }, + mode: 'production' + };`; + + const [isCopied, setIsCopied] = useState(false); + + const handleCopy = async () => { + const textToCopy = activeSyntax === 'js' ? jsCode : mjsCode; + + try { + await navigator.clipboard.writeText(textToCopy); + setIsCopied(true); + + setTimeout(() => { + setIsCopied(false); + }, 2000); + } catch (err) { + console.error('Failed to copy code: ', err); + } + }; + + const configFeatures = [ + 'Zero-config for common setups', + 'Tree-shaking out of the box', + 'Hot Module Replacement', + 'Long-term caching with content hashes', + ]; + return ( +
+
+
+

CONFIGURATION

+

+ Sensible defaults. Configurable when you need it. +

+

+ A single config file is enough for most projects. Compose loaders to + transform any input; reach for plugins when behavior is non-trivial. +

+
+ +
+
+
+ + +
+ +
+ + {activeSyntax === 'js' ? jsCode : mjsCode} + +
+ +
+ JavaScript + +
+
+ +
+

Loaders for any input

+

+ Through loaders, modules can be CommonJS, AMD, ES6 modules, CSS, + Images, JSON, Coffeescript, LESS — and your custom stuff. +

+ +
    + {configFeatures.map((feature, index) => ( +
  • + + + + {feature} +
  • + ))} +
+
+
+
+
+ ); +} diff --git a/components/HomePage/ConfigSection/index.module.css b/components/HomePage/ConfigSection/index.module.css new file mode 100644 index 00000000..c2420114 --- /dev/null +++ b/components/HomePage/ConfigSection/index.module.css @@ -0,0 +1,197 @@ +@reference "../../../styles/index.css"; + +.configSection { + @apply flex + justify-center + w-full + py-20 + border-neutral-200 + bg-neutral-100 + dark:border-neutral-800 + dark:bg-[#070c13]; +} + +.container { + @apply flex + w-[80%] + max-w-7xl + flex-col + gap-3; +} + +.configHeader { + @apply w-full + max-w-xl + text-left; +} + +.preTitle { + @apply mb-4 + flex + items-center + justify-center + text-[0.85rem] + font-normal + uppercase + tracking-wider + text-blue-600 + dark:text-blue-500 + lg:justify-start; +} + +.title { + @apply text-4xl + mb-4; +} + +.subtext { + @apply mb-8 + text-lg + leading-relaxed + text-neutral-800 + dark:text-neutral-500; +} + +.configGrid { + @apply flex + w-full + flex-col + items-start + gap-12 + lg:flex-row + lg:items-center; +} + +.codeWindow { + @apply flex + w-[95%] + flex-col + overflow-hidden + rounded-lg + bg-[#0D131C] + shadow-xl + ring-1 + ring-white/10 + lg:w-lg; +} + +.codeTabs { + @apply flex + gap-6 + border-b + border-white/10 + bg-[#0D131C] + px-4 + pt-3; +} + +.activeTab { + @apply border-b-2 + border-blue-500 + pb-2 + text-sm + font-medium + text-white; +} + +.inactiveTab { + @apply pb-2 + text-sm + font-medium + text-neutral-400 + transition-colors + hover:text-white; +} + +.codeBody { + @apply overflow-x-auto + p-6 + font-mono + text-sm + leading-relaxed; +} + +.codeFooter { + @apply flex + items-center + justify-between + border-t + border-white/10 + bg-[#0D131C] + px-4 + py-3; +} + +.codeLang { + @apply text-xs + font-medium + text-neutral-400; +} + +.copyBtn { + @apply flex + items-center + gap-2 + rounded + w-fit + h-8 + bg-blue-600 + px-3 + py-1.5 + text-xs + font-medium + text-white + transition-colors + hover:bg-blue-500; +} + +.copySVG, +.checkmarkSVG { + @apply h-4 + w-4; +} + +.features { + @apply flex + flex-1 + flex-col; +} + +.featuresTitle { + @apply mb-4 + text-2xl + font-normal + text-neutral-900 + dark:text-white; +} + +.featuresText { + @apply mb-4 + text-base + leading-relaxed + text-neutral-600 + dark:text-neutral-400; +} + +.checkList { + @apply flex + flex-col + gap-3; +} + +.checkItem { + @apply flex + items-center + gap-3 + text-sm + font-medium + text-neutral-700 + dark:text-neutral-300; +} + +.checkIcon { + @apply h-5 + w-5 + shrink-0 + text-blue-500; +} diff --git a/components/HomePage/FeaturesSection/FeaturesSection.jsx b/components/HomePage/FeaturesSection/FeaturesSection.jsx new file mode 100644 index 00000000..7a9d7161 --- /dev/null +++ b/components/HomePage/FeaturesSection/FeaturesSection.jsx @@ -0,0 +1,151 @@ +import styles from './index.module.css'; + +const Features = [ + { + title: 'Module Federation', + description: + 'Share code across separately-deployed applications at runtime. The micro-frontend pattern, done right.', + icon: ( + + + + ), + }, + { + title: 'Code splitting', + description: + "Split bundles by route, by demand, or by vendor. Load what's needed, when it's needed.", + icon: ( + + + + ), + }, + { + title: 'Tree shaking', + description: + 'Static analysis of ES modules eliminates dead code in production builds — automatically.', + icon: ( + + + + ), + }, + { + title: 'Hot module replacement', + description: + 'Edit and see the result without losing application state. The fastest feedback loop in JavaScript tooling.', + icon: ( + + + + ), + }, + { + title: 'Persistent caching', + description: + "v5's filesystem cache makes warm builds near-instant. Cold builds are 38% faster than v4 on large monorepos.", + icon: ( + + + + ), + }, + { + title: '11,000+ plugins', + description: + "The largest ecosystem in JavaScript tooling. If a build problem exists, there's a webpack plugin for it.", + icon: ( + + + + ), + }, +]; + +export default function FeaturesSection() { + return ( +
+
+
+

WHY WEBPACK

+

Built for serious applications.

+

+ The original module bundler. Used by Vercel, Shopify, GitHub, + Microsoft, and most of the modern frontend stack. +

+
+ +
+ {Features.map((feature, index) => ( +
+
{feature.icon}
+

{feature.title}

+

{feature.description}

+
+ ))} +
+
+
+ ); +} diff --git a/components/HomePage/FeaturesSection/index.module.css b/components/HomePage/FeaturesSection/index.module.css new file mode 100644 index 00000000..527fc510 --- /dev/null +++ b/components/HomePage/FeaturesSection/index.module.css @@ -0,0 +1,110 @@ +@reference "../../../styles/index.css"; + +.whySection { + @apply flex + w-full + justify-center + py-20; +} + +.container { + @apply flex + w-[80%] + max-w-7xl + flex-col + gap-3; +} + +.whyHeader { + @apply mb-4 + w-full + max-w-2xl + text-left; +} + +.preTitle { + @apply mb-4 + flex + items-center + justify-center + text-[0.85rem] + font-normal + uppercase + tracking-wider + text-blue-600 + dark:text-blue-500 + lg:justify-start; +} + +.title { + @apply text-4xl + mb-4; +} + +.subtext { + @apply mb-8 + text-lg + leading-relaxed + text-neutral-800 + dark:text-neutral-500; +} + +.gridContainer { + @apply grid + w-full + grid-cols-1 + gap-6 + md:grid-cols-2 + lg:grid-cols-3; +} + +.card { + @apply flex + flex-col + items-start + rounded-xl + border + border-neutral-200 + bg-white + p-8 + transition-shadow + hover:shadow-lg + dark:border-neutral-800 + dark:bg-[#0D131C] + dark:hover:shadow-blue-950; +} + +.iconWrapper { + @apply mb-6 + flex + h-12 + w-12 + items-center + justify-center + rounded-lg + bg-blue-50 + text-blue-600 + dark:bg-blue-900/30 + dark:text-blue-400; +} + +.iconWrapper svg { + @apply h-6 + w-6; +} + +.cardTitle { + @apply mb-3 + text-lg + font-medium + text-neutral-900 + dark:text-white; +} + +.cardDesc { + @apply m-0 + text-sm + leading-relaxed + text-neutral-600 + dark:text-neutral-400; +} diff --git a/components/HomePage/Hero/Hero.jsx b/components/HomePage/Hero/Hero.jsx new file mode 100644 index 00000000..17acff8b --- /dev/null +++ b/components/HomePage/Hero/Hero.jsx @@ -0,0 +1,94 @@ +import styles from './index.module.css'; +import pkg from '../../../package.json'; +export default function Hero() { + const webpackVersion = pkg.dependencies.webpack.replace(/[\^~]/g, ''); + return ( +
+
+
+
+

+ STATIC MODULE BUNDLER +

+ +

+ Bundle the web. +

+ +

+ webpack packs many modules into a few bundled assets. Code + splitting allows for loading parts of the application on demand — + designed for modern JavaScript apps. +

+ +
+ + Get started + + + + + + + + View on GitHub + + + + +
+
+ +
+ Webpack Cube Logo +
+
+
+ +
+
+

35M+

+

weekly downloads

+
+
+

65K+

+

GitHub stars

+
+
+

11K+

+

plugins published

+
+
+

{`v${webpackVersion}`}

+

current release

+
+
+
+ ); +} diff --git a/components/HomePage/Hero/index.module.css b/components/HomePage/Hero/index.module.css new file mode 100644 index 00000000..c49668a8 --- /dev/null +++ b/components/HomePage/Hero/index.module.css @@ -0,0 +1,194 @@ +@reference "../../../styles/index.css"; + +.hero { + @apply flex + w-full + flex-col + items-center + pt-20; +} + +.webpackContainer { + @apply flex + justify-center + w-full + border-b + border-neutral-200 + dark:border-neutral-800; +} + +.webpack { + @apply pb-20 + flex + max-w-6xl + w-[75%] + flex-col + items-center + justify-between + gap-16 + text-center + lg:flex-row + lg:gap-10 + lg:text-left; +} + +.description { + @apply w-full + max-w-full + flex-1 + lg:max-w-[520px]; +} + +.preTitle { + @apply mb-4 + flex + items-center + justify-center + text-[0.85rem] + font-normal + uppercase + tracking-wider + text-blue-600 + dark:text-blue-500 + lg:justify-start; +} + +.dot { + @apply mr-2 + inline-block + h-1.5 + w-1.5 + rounded-full + bg-blue-600 + dark:bg-blue-500; +} + +.title { + @apply mb-4 + font-normal + text-5xl + leading-[1.1] + md:text-6xl; +} + +.highlight { + @apply text-blue-600 + dark:text-blue-500; +} + +.subtext { + @apply mb-8 + text-lg + leading-relaxed + text-neutral-800 + dark:text-neutral-500; +} + +.actions { + @apply flex + items-center + justify-center + gap-4 + lg:justify-start; +} + +.primaryBtn { + @apply inline-flex + items-center + justify-center + rounded + border + border-blue-700 + bg-blue-600 + dark:bg-blue-500 + px-5 + py-3 + text-sm + font-medium + text-white + transition-colors + duration-200 + hover:bg-blue-700 + dark:hover:bg-blue-400; +} + +.arrowIcon { + @apply ml-2 + h-5 + w-5 + transition-transform + duration-200 + group-hover:translate-x-1; +} + +.primaryBtn:hover .arrowIcon { + @apply translate-x-1; +} + +.secondaryBtn { + @apply inline-flex + items-center + justify-center + rounded + border + border-[#d1d9e0] + bg-white + px-5 + py-3 + text-sm + font-medium + text-[#2c3e50] + transition-colors + duration-200 + hover:border-[#b5c0cb] + hover:bg-[#f8f9fa]; +} + +.githubIcon { + @apply ml-2 + h-4 + w-4; +} + +.logo { + @apply flex + flex-1 + items-center + justify-center + lg:justify-end; +} + +.cubeImage { + @apply aspect-square + w-75 + lg:w-95 + max-w-full + object-contain; +} + +.stats { + @apply flex + w-[90%] + max-w-350 + flex-col + items-center + justify-center + gap-6 + py-6 + text-center + dark:border-neutral-800 + lg:flex-row + lg:justify-around + lg:gap-0; +} + +.statItem h2 { + @apply text-3xl + font-medium; +} + +.statItem p { + @apply text-sm + text-neutral-800 + dark:text-neutral-500; +} diff --git a/components/HomePage/TrustedBy/TrustedBy.jsx b/components/HomePage/TrustedBy/TrustedBy.jsx new file mode 100644 index 00000000..7f8c606a --- /dev/null +++ b/components/HomePage/TrustedBy/TrustedBy.jsx @@ -0,0 +1,28 @@ +import styles from './index.module.css'; + +const companies = [ + { name: 'Vercel' }, + { name: 'Shopify' }, + { name: 'GitHub' }, + { name: 'Microsoft' }, + { name: 'Netflix' }, + { name: 'Airbnb' }, +]; + +export default function TrustedBy() { + return ( +
+
+

TRUSTED BY

+ +
+ {companies.map((company, index) => ( +
+ {company.name} +
+ ))} +
+
+
+ ); +} diff --git a/components/HomePage/TrustedBy/index.module.css b/components/HomePage/TrustedBy/index.module.css new file mode 100644 index 00000000..64e0ce76 --- /dev/null +++ b/components/HomePage/TrustedBy/index.module.css @@ -0,0 +1,55 @@ +@reference "../../../styles/index.css"; + +.trustedSection { + @apply flex + w-full + justify-center + py-16 + border-t + text-neutral-500 + dark:text-neutral-300 + border-neutral-200 + dark:border-neutral-800; +} + +.container { + @apply flex + w-[80%] + max-w-7xl + flex-col + items-center + justify-center + gap-8; +} + +.label { + @apply text-sm + font-normal + hover:text-neutral-600 + dark:hover:text-neutral-200; +} + +.logoGrid { + @apply flex + w-full + flex-wrap + items-center + justify-center + gap-8 + md:gap-16 + lg:gap-24; +} + +.logoItem { + @apply flex + items-center + justify-center + hover:text-neutral-600 + dark:hover:text-neutral-200; +} + +.companyName { + @apply text-base + font-medium + tracking-tight; +} diff --git a/layouts/Home/index.jsx b/layouts/Home/index.jsx index f237ddf5..7bcc93dc 100644 --- a/layouts/Home/index.jsx +++ b/layouts/Home/index.jsx @@ -1 +1,20 @@ -export default undefined; +import Footer from '../../components/Footer'; +import NavBar from '../../components/NavBar'; + +import FeaturesSection from '../../components/HomePage/FeaturesSection/FeaturesSection'; +import ConfigSection from '../../components/HomePage/ConfigSection/ConfigSection'; +import Hero from '../../components/HomePage/Hero/Hero'; +import TrustedBy from '../../components/HomePage/TrustedBy/TrustedBy'; + +export default function Home({ metadata }) { + return ( + <> + + + + + +