diff --git a/package.json b/package.json
index 64b6ca5c..dbcbb5a9 100644
--- a/package.json
+++ b/package.json
@@ -33,6 +33,7 @@
"nextra": "^4.6.1",
"nextra-theme-docs": "^4.6.1",
"react": "^19.2.3",
+ "react-confetti": "^6.4.0",
"react-dom": "^19.2.3",
"react-snowfall": "^2.4.0",
"sonner": "^2.0.7",
diff --git a/src/components/Confetti/Confetti.tsx b/src/components/Confetti/Confetti.tsx
new file mode 100644
index 00000000..ae518d32
--- /dev/null
+++ b/src/components/Confetti/Confetti.tsx
@@ -0,0 +1,33 @@
+'use client';
+
+import React from 'react';
+import ReactConfetti from 'react-confetti';
+
+export const Confetti = () => {
+ // We need window size for react-confetti to work properly full screen
+ // If react-use is not available we might need a custom hook or just 100vw/100vh
+ // Let's check if react-use is installed, otherwise fallback to CSS approach or basic hook
+
+ const [dimensions, setDimensions] = React.useState({ width: 0, height: 0 });
+
+ React.useEffect(() => {
+ const updateDimensions = () => {
+ setDimensions({
+ width: window.innerWidth,
+ height: window.innerHeight
+ });
+ };
+
+ // Initial set
+ updateDimensions();
+
+ window.addEventListener('resize', updateDimensions);
+ return () => window.removeEventListener('resize', updateDimensions);
+ }, []);
+
+ return (
+
+
+
+ );
+};
diff --git a/src/components/Logo/Logo.tsx b/src/components/Logo/Logo.tsx
index cae3febd..6e5aabd5 100644
--- a/src/components/Logo/Logo.tsx
+++ b/src/components/Logo/Logo.tsx
@@ -1,4 +1,4 @@
-import { ENABLE_CHRISTMAS_THEME } from '../../constants/featureFlags';
+import { ENABLE_CHRISTMAS_THEME, ENABLE_NEW_YEAR_THEME } from '../../constants/featureFlags';
export function Logo() {
return (
@@ -29,6 +29,15 @@ export function Logo() {
)}
+ {/* New Year Hat */}
+ {ENABLE_NEW_YEAR_THEME && (
+
+
+
+
+
+
+ )}
);
}
@@ -50,6 +59,15 @@ export function LogoMobile() {
)}
+ {/* New Year Hat */}
+ {ENABLE_NEW_YEAR_THEME && (
+
+
+
+
+
+
+ )}
);
}
diff --git a/src/components/Snowflakes/Snowflakes.tsx b/src/components/Snowflakes/Snowflakes.tsx
index 38f93b97..3474d914 100644
--- a/src/components/Snowflakes/Snowflakes.tsx
+++ b/src/components/Snowflakes/Snowflakes.tsx
@@ -5,15 +5,15 @@ import Snowfall from 'react-snowfall';
export const Snowflakes = () => {
return (
-
+
+
+
);
};
diff --git a/src/constants/featureFlags.ts b/src/constants/featureFlags.ts
index d6985502..e23b4e8b 100644
--- a/src/constants/featureFlags.ts
+++ b/src/constants/featureFlags.ts
@@ -1 +1,2 @@
export const ENABLE_CHRISTMAS_THEME = true;
+export const ENABLE_NEW_YEAR_THEME = false;
diff --git a/src/providers/DocsProviders.tsx b/src/providers/DocsProviders.tsx
index 13094d2d..2133d79d 100644
--- a/src/providers/DocsProviders.tsx
+++ b/src/providers/DocsProviders.tsx
@@ -10,7 +10,8 @@ import { Theme } from '@radix-ui/themes';
import { ThemeSwitch } from 'nextra-theme-docs';
import { usePathname } from 'next/navigation';
import { Snowflakes } from '../components/Snowflakes/Snowflakes';
-import { ENABLE_CHRISTMAS_THEME } from '../constants/featureFlags';
+import { Confetti } from '../components/Confetti/Confetti';
+import { ENABLE_CHRISTMAS_THEME, ENABLE_NEW_YEAR_THEME } from '../constants/featureFlags';
// Defer Nextra Search until user clicks the trigger (client-only wrapper)
const SearchDynamic = dynamic(() => import('../components/NextraSearch/NextraSearch'), { ssr: false, loading: () => });
@@ -88,8 +89,11 @@ export default function DocsProviders({ children, pageMap }) {
{isMobile && }
{ENABLE_CHRISTMAS_THEME && }
- {!isMobile && }
- {children}
+ {ENABLE_NEW_YEAR_THEME && }
+
+ {!isMobile && }
+ {children}
+
>
diff --git a/yarn.lock b/yarn.lock
index 470f7adb..cac44f8e 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -7698,6 +7698,13 @@ react-compiler-runtime@^19.1.0-rc.2:
resolved "https://registry.yarnpkg.com/react-compiler-runtime/-/react-compiler-runtime-19.1.0-rc.1-rc-af1b7da-20250421.tgz#996cf954a27b7f73ade1710e44f4303fa84e80e2"
integrity sha512-Til/juI+Zfq+eYpGYn9lFxqW5RyJDs3ThOxmg0757aMrPpfx/Zb0SnGMVJhF3vw+bEQjJiD+xPFD3+kE0WbyeA==
+react-confetti@^6.4.0:
+ version "6.4.0"
+ resolved "https://registry.yarnpkg.com/react-confetti/-/react-confetti-6.4.0.tgz#e9416b5b3c8baf6f0bb1c5a8e1e3c89babd2c837"
+ integrity sha512-5MdGUcqxrTU26I2EU7ltkWPwxvucQTuqMm8dUz72z2YMqTD6s9vMcDUysk7n9jnC+lXuCPeJJ7Knf98VEYE9Rg==
+ dependencies:
+ tween-functions "^1.2.0"
+
react-dom@^19.2.3:
version "19.2.3"
resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-19.2.3.tgz#f0b61d7e5c4a86773889fcc1853af3ed5f215b17"
@@ -8689,6 +8696,11 @@ tsx@^4.19.3:
optionalDependencies:
fsevents "~2.3.3"
+tween-functions@^1.2.0:
+ version "1.2.0"
+ resolved "https://registry.yarnpkg.com/tween-functions/-/tween-functions-1.2.0.tgz#1ae3a50e7c60bb3def774eac707acbca73bbc3ff"
+ integrity sha512-PZBtLYcCLtEcjL14Fzb1gSxPBeL7nWvGhO5ZFPGqziCcr8uvHp0NDmdjBchp6KHL+tExcg0m3NISmKxhU394dA==
+
twoslash-protocol@0.3.4:
version "0.3.4"
resolved "https://registry.yarnpkg.com/twoslash-protocol/-/twoslash-protocol-0.3.4.tgz#276ccd73dbbc99e19d8df7214b28c01a04d2294a"