The Node.js® Website

meta: remove legacy website code (#6362)

authored by Claudio W and committed by GitHub 079dacb4 3808cb76

Changed files
+339 -3344
.storybook
app
components
hooks
i18n
locales
layouts
pages
styles
types
util
+1 -1
.storybook/preview.tsx
··· 8 8 import englishLocale from '@/i18n/locales/en.json'; 9 9 10 10 import '../next.fonts'; 11 - import '../styles/new/index.css'; 11 + import '../styles/index.css'; 12 12 13 13 const preview: Preview = { 14 14 parameters: {
-3
README.md
··· 1 - > \[!IMPORTANT]\ 2 - > The **Node.js** Website is currently being redesigned; Read more [here](https://github.com/nodejs/nodejs.org/discussions/5131) to get involved! 3 - 4 1 <p align="center"> 5 2 <br /> 6 3 <a href="https://nodejs.org">
+1 -3
app/[locale]/[[...path]]/page.tsx
··· 76 76 // Gets the current full pathname for a given path 77 77 const pathname = dynamicRouter.getPathname(path); 78 78 79 - // @todo: once removed the legacy layouts remove the any casting 80 - // eslint-disable-next-line @typescript-eslint/no-explicit-any 81 - const staticGeneratedLayout = DYNAMIC_ROUTES.get(pathname) as any; 79 + const staticGeneratedLayout = DYNAMIC_ROUTES.get(pathname); 82 80 83 81 // If the current patname is a statically generated route 84 82 // it means it does not have a Markdown file nor exists under the filesystem
+2 -16
app/[locale]/error.tsx
··· 4 4 import { captureException } from '@sentry/nextjs'; 5 5 import { useTranslations } from 'next-intl'; 6 6 import type { FC } from 'react'; 7 - import { useMemo } from 'react'; 8 7 9 8 import Button from '@/components/Common/Button'; 10 - import CenteredLayout from '@/layouts/New/Centered'; 11 - import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; 12 - 13 - /** @deprecated remove legacy component when website redesign is done */ 14 - const LegacyErrorPage: FC<{ error: Error }> = ({ error }) => { 15 - useMemo(() => captureException(error), [error]); 16 - 17 - return ( 18 - <div className="container"> 19 - <h2>500: Internal Server Error</h2> 20 - <h3>This Page has thrown a non-recoverable Error</h3> 21 - </div> 22 - ); 23 - }; 9 + import CenteredLayout from '@/layouts/Centered'; 24 10 25 11 const ErrorPage: FC<{ error: Error }> = ({ error }) => { 26 12 captureException(error); ··· 47 33 ); 48 34 }; 49 35 50 - export default ENABLE_WEBSITE_REDESIGN ? ErrorPage : LegacyErrorPage; 36 + export default ErrorPage;
+6 -19
app/[locale]/layout.tsx
··· 4 4 import { getLocale } from 'next-intl/server'; 5 5 import type { FC, PropsWithChildren } from 'react'; 6 6 7 - import LegacyBaseLayout from '@/layouts/BaseLayout'; 8 - import NewBaseLayout from '@/layouts/New/Base'; 9 - import { ENABLE_WEBSITE_REDESIGN, VERCEL_ENV } from '@/next.constants.mjs'; 10 - import { IBM_PLEX_MONO, OPEN_SANS, SOURCE_SANS } from '@/next.fonts'; 7 + import BaseLayout from '@/layouts/Base'; 8 + import { VERCEL_ENV } from '@/next.constants.mjs'; 9 + import { IBM_PLEX_MONO, OPEN_SANS } from '@/next.fonts'; 11 10 import { availableLocalesMap, defaultLocale } from '@/next.locales.mjs'; 12 11 import { LocaleProvider } from '@/providers/localeProvider'; 13 12 import { ThemeProvider } from '@/providers/themeProvider'; 14 13 15 - // Uses a WebPack/TurboPack Alias for resolving Global Styles 16 - // @deprecated remove when website redesign is done 17 - // eslint-disable-next-line import/no-unresolved 18 - import 'globalStyles'; 14 + import '@/styles/index.css'; 19 15 20 - // Defines the App Fonts based on being on Website Redesign or not 21 - // @deprecated remove when website redesign is done 22 - const fontClasses = classNames(IBM_PLEX_MONO.variable, { 23 - [SOURCE_SANS.className]: !ENABLE_WEBSITE_REDESIGN, 24 - [OPEN_SANS.variable]: ENABLE_WEBSITE_REDESIGN, 25 - }); 26 - 27 - // Defines the Base Layout based on being on Website Redesign or not 28 - // @deprecated remove when website redesign is done 29 - const AppLayout = ENABLE_WEBSITE_REDESIGN ? NewBaseLayout : LegacyBaseLayout; 16 + const fontClasses = classNames(IBM_PLEX_MONO.variable, OPEN_SANS.variable); 30 17 31 18 const RootLayout: FC<PropsWithChildren> = async ({ children }) => { 32 19 const locale = await getLocale(); ··· 38 25 <body suppressHydrationWarning> 39 26 <LocaleProvider> 40 27 <ThemeProvider> 41 - <AppLayout>{children}</AppLayout> 28 + <BaseLayout>{children}</BaseLayout> 42 29 </ThemeProvider> 43 30 </LocaleProvider> 44 31
+2 -15
app/[locale]/not-found.tsx
··· 5 5 import type { FC } from 'react'; 6 6 7 7 import Button from '@/components/Common/Button'; 8 - import CenteredLayout from '@/layouts/New/Centered'; 9 - import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; 10 - 11 - /** @deprecated remove legacy component when website redesign is done */ 12 - const LegacyNotFoundPage: FC = () => { 13 - const t = useTranslations(); 14 - 15 - return ( 16 - <div className="container"> 17 - <h2>{t('pages.404.title')}</h2> 18 - <h3>{t('pages.404.description')}</h3> 19 - </div> 20 - ); 21 - }; 8 + import CenteredLayout from '@/layouts/Centered'; 22 9 23 10 const NotFoundPage: FC = () => { 24 11 const t = useTranslations(); ··· 42 29 ); 43 30 }; 44 31 45 - export default ENABLE_WEBSITE_REDESIGN ? NotFoundPage : LegacyNotFoundPage; 32 + export default NotFoundPage;
+3 -21
app/global-error.tsx
··· 2 2 3 3 import { ArrowRightIcon } from '@heroicons/react/24/solid'; 4 4 import { captureException } from '@sentry/nextjs'; 5 - import ErrorComponent from 'next/error'; 6 5 import type { FC } from 'react'; 7 - import { useMemo } from 'react'; 8 6 9 7 import Button from '@/components/Common/Button'; 10 - import BaseLayout from '@/layouts/BaseLayout'; 11 - import CenteredLayout from '@/layouts/New/Centered'; 12 - import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; 13 - 14 - /** @deprecated remove legacy component when website redesign is done */ 15 - const LegacyGlobalErrorPage: FC<{ error: Error }> = ({ error }) => { 16 - useMemo(() => captureException(error), [error]); 17 - 18 - return ( 19 - <html> 20 - <body> 21 - <ErrorComponent statusCode={500} /> 22 - </body> 23 - </html> 24 - ); 25 - }; 8 + import BaseLayout from '@/layouts/Base'; 9 + import CenteredLayout from '@/layouts/Centered'; 26 10 27 11 const GlobalErrorPage: FC<{ error: Error }> = ({ error }) => { 28 12 captureException(error); ··· 52 36 ); 53 37 }; 54 38 55 - export default ENABLE_WEBSITE_REDESIGN 56 - ? GlobalErrorPage 57 - : LegacyGlobalErrorPage; 39 + export default GlobalErrorPage;
+1 -5
components/Common/CodeBox/index.tsx
··· 10 10 11 11 import Button from '@/components/Common/Button'; 12 12 import { useCopyToClipboard, useNotification } from '@/hooks'; 13 - import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; 14 13 15 14 import styles from './index.module.css'; 16 15 ··· 69 68 const CodeBox: FC<PropsWithChildren<CodeBoxProps>> = ({ 70 69 children, 71 70 language, 72 - // For now we only want to render the Copy Button by default 73 - // if the Website Redesign is Enabled 74 - // @todo remove this check once we migrate to website redesign 75 - showCopyButton = ENABLE_WEBSITE_REDESIGN, 71 + showCopyButton = true, 76 72 }) => { 77 73 const ref = useRef<HTMLPreElement>(null); 78 74
+1
components/Common/CrossLink/index.module.css
··· 10 10 border-neutral-300 11 11 bg-white 12 12 p-3 13 + no-underline 13 14 dark:border-neutral-900 14 15 dark:bg-neutral-950; 15 16
+1 -1
components/Common/Search/States/WithSearchResult.tsx
··· 15 15 }; 16 16 17 17 export const WithSearchResult: FC<SearchResultProps> = props => { 18 - const isAPIResult = props.hit.document.siteSection.toLowerCase() === 'api'; 18 + const isAPIResult = props.hit.document.siteSection.toLowerCase() === 'docs'; 19 19 const basePath = isAPIResult ? BASE_URL : ''; 20 20 const path = `${basePath}/${props.hit.document.path}`; 21 21
+3 -6
components/Common/Search/index.module.css
··· 2 2 @apply relative 3 3 w-52 4 4 rounded-md 5 - bg-neutral-100 5 + bg-neutral-200 6 6 py-2 7 7 pl-9 8 8 pr-4 9 9 text-left 10 10 text-sm 11 11 text-neutral-700 12 - transition-colors 13 - duration-200 14 - ease-in-out 15 - hover:bg-neutral-200 16 - hover:text-neutral-800 12 + hover:bg-neutral-300 13 + hover:text-neutral-900 17 14 dark:bg-neutral-900 18 15 dark:text-neutral-600 19 16 dark:hover:bg-neutral-800
+2
components/Common/Search/index.tsx
··· 35 35 className={styles.searchButton} 36 36 > 37 37 <MagnifyingGlassIcon className={styles.magnifyingGlassIcon} /> 38 + 38 39 {t('components.search.searchBox.placeholder')} 39 40 </button> 41 + 40 42 {isOpen ? <WithSearchBox onClose={closeSearchBox} /> : null} 41 43 </> 42 44 );
-36
components/Downloads/DownloadList.tsx
··· 1 - import { useTranslations } from 'next-intl'; 2 - import type { FC } from 'react'; 3 - 4 - import Link from '@/components/Link'; 5 - import { useSiteNavigation } from '@/hooks/server'; 6 - import type { NodeRelease } from '@/types'; 7 - 8 - const DownloadList: FC<NodeRelease> = ({ versionWithPrefix }) => { 9 - const t = useTranslations(); 10 - 11 - const { getSideNavigation } = useSiteNavigation(); 12 - 13 - const [[, downloadNavigationItems]] = getSideNavigation(['download'], { 14 - shaSums: { nodeVersion: versionWithPrefix }, 15 - allDownloads: { nodeVersion: versionWithPrefix }, 16 - }); 17 - 18 - return ( 19 - <section> 20 - <ul> 21 - {downloadNavigationItems.items.map(([key, { label, link }]) => ( 22 - <li key={key}> 23 - <Link href={link}>{label}</Link> 24 - {key === 'shaSums' && ( 25 - <a href="https://github.com/nodejs/node#verifying-binaries"> 26 - {t('components.downloadList.links.shaSums.howToVerify')} 27 - </a> 28 - )} 29 - </li> 30 - ))} 31 - </ul> 32 - </section> 33 - ); 34 - }; 35 - 36 - export default DownloadList;
-254
components/Downloads/PrimaryDownloadMatrix.tsx
··· 1 - 'use client'; 2 - 3 - import classNames from 'classnames'; 4 - import type { FC } from 'react'; 5 - import semVer from 'semver'; 6 - 7 - import Link from '@/components/Link'; 8 - import WithCurrentOS from '@/components/withCurrentOS'; 9 - import { useClientContext } from '@/hooks'; 10 - import { DIST_URL } from '@/next.constants.mjs'; 11 - import type { NodeRelease } from '@/types'; 12 - 13 - // @TODO: Legacy Component to be removed in the Website Redesign 14 - const PrimaryDownloadMatrix: FC<NodeRelease> = ({ 15 - version, 16 - versionWithPrefix, 17 - isLts, 18 - npm, 19 - }) => { 20 - const { 21 - frontmatter: { downloads }, 22 - } = useClientContext(); 23 - 24 - const hasWindowsArm64 = semVer.satisfies(version, '>= 19.9.0'); 25 - 26 - const getIsVersionClassName = (isCurrent: boolean) => 27 - classNames({ 'is-version': isCurrent }); 28 - 29 - return ( 30 - <section> 31 - <p className="color-lightgray"> 32 - {downloads.currentVersion}: <strong>{version}</strong> ( 33 - {downloads.includes || 'includes'} npm {npm}) 34 - </p> 35 - <p>{downloads.intro}</p> 36 - 37 - <div className="download-hero full-width"> 38 - <ul className="no-padding download-version-toggle"> 39 - <li> 40 - <Link 41 - className={getIsVersionClassName(isLts)} 42 - href="/download/" 43 - title={`${downloads['display-hint']} ${downloads.lts}`} 44 - > 45 - <div className="title">{downloads.lts}</div> 46 - <div className="tag">{downloads['tagline-lts']}</div> 47 - </Link> 48 - </li> 49 - <li> 50 - <Link 51 - className={getIsVersionClassName(!isLts)} 52 - href="/download/current" 53 - title={`${downloads['display-hint']} ${downloads.current}`} 54 - > 55 - <div className="title">{downloads.current}</div> 56 - <div className="tag">{downloads['tagline-current']}</div> 57 - </Link> 58 - </li> 59 - </ul> 60 - <ul className="no-padding download-platform"> 61 - <li> 62 - <WithCurrentOS> 63 - {({ currentOS }) => ( 64 - <a 65 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-x${currentOS.bitness}.msi`} 66 - data-version={versionWithPrefix} 67 - > 68 - <svg 69 - className="download-logo" 70 - width="50" 71 - height="50" 72 - viewBox="0 0 50 50" 73 - focusable="false" 74 - > 75 - <path d="M1.589 23.55L1.572 8.24l18.839-2.558V23.55zM23.55 5.225l25.112-3.654V23.55H23.55zM48.669 26.69l-.006 21.979-25.112-3.533V26.69zM20.41 44.736l-18.824-2.58-.001-15.466H20.41z" /> 76 - </svg> 77 - {downloads.WindowsInstaller} 78 - <p className="small color-lightgray"> 79 - node-{versionWithPrefix}-x{currentOS.bitness}.msi 80 - </p> 81 - </a> 82 - )} 83 - </WithCurrentOS> 84 - </li> 85 - <li> 86 - <a 87 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.pkg`} 88 - > 89 - <svg 90 - className="download-logo" 91 - width="50" 92 - height="50" 93 - viewBox="0 0 50 50" 94 - focusable="false" 95 - > 96 - <path d="M39.054 34.065q-1.093 3.504-3.448 7.009-3.617 5.495-7.205 5.495-1.374 0-3.925-.897-2.411-.897-4.233-.897-1.71 0-3.981.925-2.271.953-3.701.953-4.261 0-8.439-7.261Q.001 32.075.001 25.29q0-6.392 3.168-10.485 3.14-4.037 7.962-4.037 2.019 0 4.962.841 2.916.841 3.869.841 1.262 0 4.009-.953 2.86-.953 4.85-.953 3.336 0 5.972 1.822 1.458 1.009 2.916 2.804-2.215 1.878-3.196 3.308-1.822 2.635-1.822 5.803 0 3.476 1.934 6.252t4.43 3.533zM28.512 1.179q0 1.71-.813 3.813-.841 2.103-2.607 3.869-1.514 1.514-3.028 2.019-1.037.308-2.916.477.084-4.177 2.187-7.205 2.075-3 7.009-4.149.028.084.07.308t.07.308q0 .112.014.28t.014.28z" /> 97 - </svg> 98 - {downloads.MacOSInstaller} 99 - <p className="small color-lightgray"> 100 - node-{versionWithPrefix}.pkg 101 - </p> 102 - </a> 103 - </li> 104 - <li> 105 - <a 106 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.tar.gz`} 107 - > 108 - <svg 109 - className="download-logo" 110 - width="50" 111 - height="50" 112 - viewBox="0 0 50 50" 113 - focusable="false" 114 - > 115 - <path d="M25.03.934L.159 11.65l24.895 10.632 25.152-10.656L25.03.935zm1.02 22.686v25.686l24.188-11.483V13.345L26.05 23.62zM.001 37.824l24.27 11.483V23.621L.001 13.346v24.478z" /> 116 - </svg> 117 - {downloads.SourceCode} 118 - <p className="small color-lightgray"> 119 - node-{versionWithPrefix}.tar.gz 120 - </p> 121 - </a> 122 - </li> 123 - </ul> 124 - </div> 125 - 126 - <table className="download-matrix full-width"> 127 - <tbody> 128 - <tr> 129 - <th>{downloads.WindowsInstaller} (.msi)</th> 130 - <td colSpan={hasWindowsArm64 ? 1 : 2}> 131 - <a 132 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-x86.msi`} 133 - > 134 - 32-bit 135 - </a> 136 - </td> 137 - <td colSpan={2}> 138 - <a 139 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-x64.msi`} 140 - > 141 - 64-bit 142 - </a> 143 - </td> 144 - {hasWindowsArm64 && ( 145 - <td colSpan={1}> 146 - <a 147 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-arm64.msi`} 148 - > 149 - ARM64 150 - </a> 151 - </td> 152 - )} 153 - </tr> 154 - 155 - <tr> 156 - <th>{downloads.WindowsBinary} (.zip)</th> 157 - <td colSpan={hasWindowsArm64 ? 1 : 2}> 158 - <a 159 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-win-x86.zip`} 160 - > 161 - 32-bit 162 - </a> 163 - </td> 164 - <td colSpan={2}> 165 - <a 166 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-win-x64.zip`} 167 - > 168 - 64-bit 169 - </a> 170 - </td> 171 - {hasWindowsArm64 && ( 172 - <td colSpan={1}> 173 - <a 174 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-win-arm64.zip`} 175 - > 176 - ARM64 177 - </a> 178 - </td> 179 - )} 180 - </tr> 181 - 182 - <tr> 183 - <th>{downloads.MacOSInstaller} (.pkg)</th> 184 - <td colSpan={4}> 185 - <a 186 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.pkg`} 187 - > 188 - 64-bit / ARM64 189 - </a> 190 - </td> 191 - </tr> 192 - <tr> 193 - <th>{downloads.MacOSBinary} (.tar.gz)</th> 194 - <td colSpan={2}> 195 - <a 196 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-darwin-x64.tar.gz`} 197 - > 198 - 64-bit 199 - </a> 200 - </td> 201 - <td colSpan={2}> 202 - <a 203 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-darwin-arm64.tar.gz`} 204 - > 205 - ARM64 206 - </a> 207 - </td> 208 - </tr> 209 - 210 - <tr> 211 - <th>{downloads.LinuxBinaries} (x64)</th> 212 - <td colSpan={4}> 213 - <a 214 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-x64.tar.xz`} 215 - > 216 - 64-bit 217 - </a> 218 - </td> 219 - </tr> 220 - <tr> 221 - <th>{downloads.LinuxBinaries} (ARM)</th> 222 - <td colSpan={2}> 223 - <a 224 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-armv7l.tar.xz`} 225 - > 226 - ARMv7 227 - </a> 228 - </td> 229 - <td colSpan={2}> 230 - <a 231 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-arm64.tar.xz`} 232 - > 233 - ARMv8 234 - </a> 235 - </td> 236 - </tr> 237 - 238 - <tr> 239 - <th>{downloads.SourceCode}</th> 240 - <td colSpan={4}> 241 - <a 242 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}.tar.gz`} 243 - > 244 - node-{versionWithPrefix}.tar.gz 245 - </a> 246 - </td> 247 - </tr> 248 - </tbody> 249 - </table> 250 - </section> 251 - ); 252 - }; 253 - 254 - export default PrimaryDownloadMatrix;
+8 -2
components/Downloads/Release/PlatformDropdown.tsx
··· 5 5 import type { FC } from 'react'; 6 6 7 7 import Select from '@/components/Common/Select'; 8 + import Choco from '@/components/Icons/Platform/Choco'; 8 9 import Docker from '@/components/Icons/Platform/Docker'; 9 10 import Homebrew from '@/components/Icons/Platform/Homebrew'; 10 11 import NVM from '@/components/Icons/Platform/NVM'; ··· 26 27 const disabledItems = []; 27 28 28 29 if (os === 'WIN') { 29 - disabledItems.push('BREW'); 30 + disabledItems.push('BREW', 'NVM'); 30 31 } 31 32 32 33 if (os === 'LINUX') { 33 - disabledItems.push('DOCKER'); 34 + disabledItems.push('DOCKER', 'CHOCO'); 35 + } 36 + 37 + if (os === 'MAC') { 38 + disabledItems.push('CHOCO'); 34 39 } 35 40 36 41 const releaseSupportsHomebrew = supportedHomebrewVersions.includes( ··· 71 76 NVM: <NVM width={16} height={16} />, 72 77 BREW: <Homebrew width={16} height={16} />, 73 78 DOCKER: <Docker width={16} height={16} />, 79 + CHOCO: <Choco width={16} height={16} />, 74 80 }, 75 81 disabledItems, 76 82 })}
+5 -7
components/Downloads/Release/ReleaseCodeBox.tsx
··· 14 14 const memoizedShiki = getShiki(); 15 15 16 16 const ReleaseCodeBox: FC = () => { 17 - const { 18 - platform, 19 - os, 20 - release: { major }, 21 - } = useContext(ReleaseContext); 17 + const { platform, os, release } = useContext(ReleaseContext); 22 18 23 19 const [code, setCode] = useState(''); 24 20 const t = useTranslations(); 25 21 26 22 useEffect(() => { 27 - const updatedCode = getNodeDownloadSnippet(major, os)[platform]; 23 + const updatedCode = getNodeDownloadSnippet(release, os)[platform]; 28 24 // Docker and NVM support downloading tags/versions by their full release number 29 25 // but usually we should recommend users to download "major" versions 30 26 // since our Downlooad Buttons get the latest minor of a major, it does make sense ··· 32 28 memoizedShiki 33 29 .then(shiki => highlightToHtml(shiki)(updatedCode, 'bash')) 34 30 .then(setCode); 35 - }, [major, os, platform]); 31 + // Only react when the specific release number changed 32 + // eslint-disable-next-line react-hooks/exhaustive-deps 33 + }, [release.versionWithPrefix, os, platform]); 36 34 37 35 return ( 38 36 <div className="mb-2 mt-6 flex min-h-80 flex-col gap-2">
-73
components/Downloads/SecondaryDownloadMatrix.tsx
··· 1 - import type { FC } from 'react'; 2 - 3 - import DownloadList from '@/components/Downloads/DownloadList'; 4 - import WithNodeRelease from '@/components/withNodeRelease'; 5 - import { useClientContext } from '@/hooks/server'; 6 - import { DIST_URL } from '@/next.constants.mjs'; 7 - import type { NodeRelease } from '@/types'; 8 - 9 - // @TODO: Legacy Component to be removed in the Website Redesign 10 - const SecondaryDownloadMatrix: FC<NodeRelease> = ({ 11 - versionWithPrefix, 12 - status, 13 - }) => { 14 - const { 15 - frontmatter: { additional }, 16 - } = useClientContext(); 17 - 18 - return ( 19 - <section> 20 - <h2>{additional.headline}</h2> 21 - <table className="download-matrix full-width"> 22 - <tbody> 23 - <tr> 24 - <th>{additional.DockerImage}</th> 25 - <td> 26 - <a href="https://hub.docker.com/_/node/"> 27 - {additional.officialDockerImage} 28 - </a> 29 - </td> 30 - </tr> 31 - 32 - <tr> 33 - <th>{additional.LinuxPowerSystems}</th> 34 - <td> 35 - <a 36 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-ppc64le.tar.xz`} 37 - > 38 - 64-bit 39 - </a> 40 - </td> 41 - </tr> 42 - 43 - <tr> 44 - <th>{additional.LinuxSystemZ}</th> 45 - <td> 46 - <a 47 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-linux-s390x.tar.xz`} 48 - > 49 - 64-bit 50 - </a> 51 - </td> 52 - </tr> 53 - <tr> 54 - <th>{additional.AIXPowerSystems}</th> 55 - <td> 56 - <a 57 - href={`${DIST_URL}${versionWithPrefix}/node-${versionWithPrefix}-aix-ppc64.tar.gz`} 58 - > 59 - 64-bit 60 - </a> 61 - </td> 62 - </tr> 63 - </tbody> 64 - </table> 65 - 66 - <WithNodeRelease status={status}> 67 - {({ release }) => <DownloadList {...release} />} 68 - </WithNodeRelease> 69 - </section> 70 - ); 71 - }; 72 - 73 - export default SecondaryDownloadMatrix;
-45
components/Footer.tsx
··· 1 - import type { FC } from 'react'; 2 - 3 - import Link from '@/components/Link'; 4 - 5 - type FooterProps = { className?: string }; 6 - 7 - // Note.: We don't expect to translate these items as we're going to replace with `nodejs/nodejs.dev` footer 8 - const Footer: FC<FooterProps> = ({ className }) => ( 9 - <footer className={className}> 10 - <div className="container"> 11 - <div className="openjsfoundation-footer"> 12 - <p> 13 - Copyright <a href="https://openjsf.org">OpenJS Foundation</a> and 14 - Node.js contributors. All rights reserved. The{' '} 15 - <a href="https://openjsf.org">OpenJS Foundation</a> has registered 16 - trademarks and uses trademarks. For a list of trademarks of the{' '} 17 - <a href="https://openjsf.org">OpenJS Foundation</a>, please see our{' '} 18 - <a href="https://trademark-policy.openjsf.org">Trademark Policy</a>{' '} 19 - and <a href="https://trademark-list.openjsf.org">Trademark List</a>. 20 - Trademarks and logos not indicated on the{' '} 21 - <a href="https://trademark-list.openjsf.org"> 22 - list of OpenJS Foundation trademarks 23 - </a>{' '} 24 - are trademarks&trade; or registered&reg; trademarks of their 25 - respective holders. Use of them does not imply any affiliation with or 26 - endorsement by them. 27 - </p> 28 - <p className="openjsfoundation-footer-links"> 29 - <a href="https://openjsf.org">The OpenJS Foundation</a> 30 - &nbsp;|&nbsp; 31 - <a href="https://trademark-policy.openjsf.org">Trademark Policy</a> 32 - &nbsp;|&nbsp; 33 - <a href="https://privacy-policy.openjsf.org">Privacy Policy</a> 34 - &nbsp;|&nbsp; 35 - <a href="https://code-of-conduct.openjsf.org">Code of Conduct</a> 36 - &nbsp;|&nbsp; 37 - <Link href="/about/security-reporting">Security Reporting</Link> 38 - </p> 39 - <div className="openjsfoundation-footer-edit"></div> 40 - </div> 41 - </div> 42 - </footer> 43 - ); 44 - 45 - export default Footer;
-108
components/Header.tsx
··· 1 - 'use client'; 2 - 3 - import Image from 'next/image'; 4 - import { useTranslations } from 'next-intl'; 5 - import { useTheme } from 'next-themes'; 6 - import type { FC, PropsWithChildren } from 'react'; 7 - import { useState } from 'react'; 8 - 9 - import Link from '@/components/Link'; 10 - import { useClientContext } from '@/hooks'; 11 - import { BASE_PATH } from '@/next.constants.mjs'; 12 - import { availableLocales } from '@/next.locales.mjs'; 13 - 14 - const Header: FC<PropsWithChildren> = ({ children }) => { 15 - const [showLangPicker, setShowLangPicker] = useState(false); 16 - const { resolvedTheme, setTheme } = useTheme(); 17 - 18 - const { pathname } = useClientContext(); 19 - const t = useTranslations(); 20 - 21 - const toggleLanguage = t('components.header.buttons.toggleLanguage'); 22 - const toggleTheme = t('components.header.buttons.toggleTheme'); 23 - 24 - return ( 25 - <header aria-label="Primary"> 26 - <div className="container"> 27 - <Link href="/" className="logo"> 28 - <Image 29 - priority 30 - width="111" 31 - height="33" 32 - src={`${BASE_PATH}/static/images/logo.svg`} 33 - alt="Node.js" 34 - /> 35 - </Link> 36 - 37 - {children} 38 - 39 - <div className="switchers"> 40 - <button 41 - className="theme-switcher" 42 - type="button" 43 - title={toggleTheme} 44 - aria-label={toggleTheme} 45 - onClick={() => 46 - setTheme(resolvedTheme === 'dark' ? 'light' : 'dark') 47 - } 48 - > 49 - <Image 50 - priority 51 - width="28" 52 - height="28" 53 - className="dark-image" 54 - src={`${BASE_PATH}/static/images/light-mode.svg`} 55 - alt="Theme Switcher" 56 - /> 57 - 58 - <Image 59 - priority 60 - width="28" 61 - height="28" 62 - className="light-image" 63 - src={`${BASE_PATH}/static/images/dark-mode.svg`} 64 - alt="Theme Switcher" 65 - /> 66 - </button> 67 - 68 - <button 69 - className="lang-picker-toggler" 70 - type="button" 71 - title={toggleLanguage} 72 - aria-label={toggleLanguage} 73 - onClick={() => setShowLangPicker(!showLangPicker)} 74 - aria-controls="lang-picker" 75 - aria-expanded="false" 76 - > 77 - <Image 78 - priority 79 - width="25" 80 - height="28" 81 - src={`${BASE_PATH}/static/images/language-picker.svg`} 82 - alt="Language Switcher" 83 - /> 84 - </button> 85 - </div> 86 - 87 - {showLangPicker && ( 88 - <ul className="lang-picker"> 89 - {availableLocales.map(locale => ( 90 - <li key={locale.code}> 91 - <Link 92 - title={locale.name} 93 - locale={locale.code} 94 - href={pathname} 95 - onClick={() => setShowLangPicker(false)} 96 - > 97 - {locale.localName} 98 - </Link> 99 - </li> 100 - ))} 101 - </ul> 102 - )} 103 - </div> 104 - </header> 105 - ); 106 - }; 107 - 108 - export default Header;
-69
components/Home/HomeDownloadButton.tsx
··· 1 - 'use client'; 2 - 3 - import { useTranslations } from 'next-intl'; 4 - import type { FC } from 'react'; 5 - 6 - import Link from '@/components/Link'; 7 - import { useDetectOS } from '@/hooks'; 8 - import { DIST_URL } from '@/next.constants.mjs'; 9 - import type { NodeRelease } from '@/types'; 10 - import { getNodeDownloadUrl } from '@/util/getNodeDownloadUrl'; 11 - import { getNodejsChangelog } from '@/util/getNodeJsChangelog'; 12 - 13 - const HomeDownloadButton: FC<NodeRelease> = ({ 14 - major, 15 - version, 16 - versionWithPrefix, 17 - isLts, 18 - }) => { 19 - const { os, bitness } = useDetectOS(); 20 - const t = useTranslations(); 21 - 22 - const nodeDownloadLink = getNodeDownloadUrl(versionWithPrefix, os, bitness); 23 - const nodeApiLink = `${DIST_URL}latest-v${major}.x/docs/api/`; 24 - const nodeAllDownloadsLink = `/download${isLts ? '/' : '/current'}`; 25 - 26 - const downloadFile = t('components.home.homeDownloadButton.download', { 27 - version, 28 - isLts, 29 - }); 30 - 31 - return ( 32 - <div className="home-downloadblock"> 33 - <a 34 - href={nodeDownloadLink} 35 - className="home-downloadbutton" 36 - title={downloadFile} 37 - data-version={versionWithPrefix} 38 - > 39 - {downloadFile} 40 - 41 - <small> 42 - {t('components.home.homeDownloadButton.tagline', { isLts })} 43 - </small> 44 - </a> 45 - 46 - <ul className="list-divider-pipe home-secondary-links"> 47 - <li> 48 - <Link href={nodeAllDownloadsLink}> 49 - {t('components.home.homeDownloadButton.otherDownloads')} 50 - </Link> 51 - </li> 52 - 53 - <li> 54 - <a href={getNodejsChangelog(versionWithPrefix)}> 55 - {t('components.home.homeDownloadButton.changelog')} 56 - </a> 57 - </li> 58 - 59 - <li> 60 - <a href={nodeApiLink}> 61 - {t('components.home.homeDownloadButton.apiDocs')} 62 - </a> 63 - </li> 64 - </ul> 65 - </div> 66 - ); 67 - }; 68 - 69 - export default HomeDownloadButton;
+78
components/Icons/Platform/Choco.tsx
··· 1 + import type { FC, SVGProps } from 'react'; 2 + 3 + const Choco: FC<SVGProps<SVGSVGElement>> = props => ( 4 + <svg 5 + width="32" 6 + height="32" 7 + viewBox="0 0 31.7 28.4" 8 + enableBackground="new 0 0 31.7 28.4" 9 + xmlns="http://www.w3.org/2000/svg" 10 + {...props} 11 + > 12 + <g> 13 + <polygon 14 + fill="#924716" 15 + points="27.6,27.2 5.7,27.2 5.7,1 27.6,1 27.6,6.9" 16 + /> 17 + <polygon fill="#793812" points="27.6,1 27.6,27.2 25.7,27.2 25.7,2.6" /> 18 + <polygon fill="#9F5326" points="25.4,2.6 3.5,2.6 3.5,1 27.3,1" /> 19 + <g> 20 + <polygon 21 + fill="#80B5E3" 22 + points="27.6,27.2 3.7,27.2 3.7,1 8.5,1 12.6,4.2 16.6,2.6 19.1,5.7 23.8,4.9 25.7,10.7 27.6,18.1 23 + 30.5,21.1 29,23.6 31.7,28.4" 24 + /> 25 + <polygon 26 + fill="#80B5E3" 27 + points="3.7,27.2 3.7,1 0,0 1.9,4.2 0,7.5 1.9,10.8 0,14.1 1.9,17.3 0,20.6 1.9,23.9 0,28.4" 28 + /> 29 + </g> 30 + <polygon 31 + opacity="0.2" 32 + fill="#FFFFFF" 33 + points="10.4,2.6 5.4,2.6 3.5,1 8.3,1" 34 + /> 35 + <g> 36 + <path 37 + fill="#924716" 38 + d="M18.3,13.7c-0.7,0.6-2.5,1.9-4.4,2.3c-2.3,0.5-3.6-1.4-3.1-3.2c0.5-2.1,2.8-3.7,4.8-3 39 + c0.9,0.3,0.6,1.5,0.3,2.1c-0.8,1.5,0.3,1.7,0.8,1.2c1.5-1.6,2.4-4.3-0.2-5.3c-4-1.5-7.3,2.2-8.4,5.2c-1.7,4.8,2.4,9,7.1,5.8 40 + c1.2-0.8,2.6-2.2,3.5-3.4C19.5,14.2,19,13.1,18.3,13.7z" 41 + /> 42 + <ellipse 43 + transform="matrix(0.707 -0.7072 0.7072 0.707 -1.547 19.2306)" 44 + fill="#924716" 45 + cx="22.4" 46 + cy="11.5" 47 + rx="1.6" 48 + ry="1.1" 49 + /> 50 + <ellipse 51 + transform="matrix(0.707 -0.7072 0.7072 0.707 -4.7882 20.1076)" 52 + fill="#924716" 53 + cx="21.9" 54 + cy="15.8" 55 + rx="1.6" 56 + ry="1.1" 57 + /> 58 + </g> 59 + <polygon 60 + opacity="0.2" 61 + fill="#FFFFFF" 62 + points="5.7,25.5 3.7,27.2 3.7,1 5.7,2.6" 63 + /> 64 + <g opacity="0.2"> 65 + <polygon 66 + fill="#342565" 67 + points="27.6,27.2 3.7,27.2 5.7,25.5 25.7,25.5" 68 + /> 69 + <polygon 70 + fill="#342565" 71 + points="27.6,27.2 25.7,25.5 25.7,10.7 27.6,18.1" 72 + /> 73 + </g> 74 + </g> 75 + </svg> 76 + ); 77 + 78 + export default Choco;
+1 -1
components/MDX/SearchPage/index.tsx
··· 71 71 : {}; 72 72 73 73 const getDocumentURL = (siteSection: string, path: string) => { 74 - const isAPIResult = siteSection.toLowerCase() === 'api'; 74 + const isAPIResult = siteSection.toLowerCase() === 'docs'; 75 75 const basePath = isAPIResult ? BASE_URL : ''; 76 76 return `${basePath}/${path}`; 77 77 };
-31
components/Pagination.tsx
··· 1 - import { useTranslations } from 'next-intl'; 2 - import type { FC } from 'react'; 3 - 4 - import Link from '@/components/Link'; 5 - import type { BlogPagination } from '@/types'; 6 - 7 - type PaginationProps = BlogPagination & { category: string }; 8 - 9 - const Pagination: FC<PaginationProps> = ({ category, next, prev }) => { 10 - const t = useTranslations(); 11 - 12 - return ( 13 - <nav aria-label="pagination" className="pagination"> 14 - {prev && ( 15 - <Link href={`/blog/${category}/page/${prev}`}> 16 - &lt; {t('components.pagination.previous')} 17 - </Link> 18 - )} 19 - 20 - {prev && next && ' | '} 21 - 22 - {next && ( 23 - <Link href={`/blog/${category}/page/${next}`}> 24 - {t('components.pagination.next')} &gt; 25 - </Link> 26 - )} 27 - </nav> 28 - ); 29 - }; 30 - 31 - export default Pagination;
-38
components/SideNavigation.tsx
··· 1 - import type { RichTranslationValues } from 'next-intl'; 2 - import type { FC } from 'react'; 3 - 4 - import ActiveLink from '@/components/Common/ActiveLink'; 5 - import { useSiteNavigation } from '@/hooks/server'; 6 - import type { NavigationKeys } from '@/types'; 7 - 8 - type SideNavigationProps = { 9 - navigationKeys: Array<NavigationKeys>; 10 - context?: Record<string, RichTranslationValues>; 11 - }; 12 - 13 - const SideNavigation: FC<SideNavigationProps> = ({ 14 - navigationKeys, 15 - context, 16 - }) => { 17 - const { getSideNavigation } = useSiteNavigation(); 18 - 19 - const sideNavigation = getSideNavigation(navigationKeys, context); 20 - 21 - const mapItems = (items: ReturnType<typeof getSideNavigation>) => { 22 - return items.map(([, { link, label, items }]) => ( 23 - <li key={`${link}-${label}`}> 24 - {link ? <ActiveLink href={link}>{label}</ActiveLink> : label} 25 - 26 - {items && items.length > 0 && <ul>{mapItems(items)}</ul>} 27 - </li> 28 - )); 29 - }; 30 - 31 - return ( 32 - <nav aria-label="secondary"> 33 - <ul>{mapItems(sideNavigation)}</ul> 34 - </nav> 35 - ); 36 - }; 37 - 38 - export default SideNavigation;
-24
components/TopNavigation.tsx
··· 1 - import type { FC } from 'react'; 2 - 3 - import ActiveLink from '@/components/Common/ActiveLink'; 4 - import { useSiteNavigation } from '@/hooks/server'; 5 - 6 - const TopNavigation: FC = () => { 7 - const { navigationItems } = useSiteNavigation(); 8 - 9 - return ( 10 - <nav aria-label="primary"> 11 - <ul className="list-divider-pipe"> 12 - {navigationItems.map(([key, { link, label }]) => ( 13 - <li key={key}> 14 - <ActiveLink href={link} allowSubPath={link.startsWith('/')}> 15 - {label} 16 - </ActiveLink> 17 - </li> 18 - ))} 19 - </ul> 20 - </nav> 21 - ); 22 - }; 23 - 24 - export default TopNavigation;
+2
components/__design__/platform-logos.stories.tsx
··· 1 1 import type { Meta as MetaObj, StoryObj } from '@storybook/react'; 2 2 3 3 import Apple from '@/components/Icons/Platform/Apple'; 4 + import Choco from '@/components/Icons/Platform/Choco'; 4 5 import Docker from '@/components/Icons/Platform/Docker'; 5 6 import Generic from '@/components/Icons/Platform/Generic'; 6 7 import Homebrew from '@/components/Icons/Platform/Homebrew'; ··· 23 24 </div> 24 25 <div className="flex flex-col items-center gap-4"> 25 26 <Generic width={64} height={64} /> 27 + <Choco width={64} height={64} /> 26 28 </div> 27 29 </div> 28 30 ),
+14 -45
components/withLayout.tsx
··· 1 1 import type { FC, PropsWithChildren } from 'react'; 2 2 3 - import LegacyAboutLayout from '@/layouts/AboutLayout'; 4 - import LegacyBlogCategoryLayout from '@/layouts/BlogCategoryLayout'; 5 - import LegacyBlogPostLayout from '@/layouts/BlogPostLayout'; 6 - import LegacyDefaultLayout from '@/layouts/DefaultLayout'; 7 - import LegacyDocsLayout from '@/layouts/DocsLayout'; 8 - import LegacyDownloadLayout from '@/layouts/DownloadLayout'; 9 - import LegacyIndexLayout from '@/layouts/IndexLayout'; 10 - import LegacyLearnLayout from '@/layouts/LearnLayout'; 11 - import AboutLayout from '@/layouts/New/About'; 12 - import BlogLayout from '@/layouts/New/Blog'; 13 - import DefaultLayout from '@/layouts/New/Default'; 14 - import DownloadLayout from '@/layouts/New/Download'; 15 - import HomeLayout from '@/layouts/New/Home'; 16 - import LearnLayout from '@/layouts/New/Learn'; 17 - import PostLayout from '@/layouts/New/Post'; 18 - import SearchLayout from '@/layouts/New/Search'; 19 - import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; 20 - import type { Layouts, LegacyLayouts } from '@/types'; 3 + import AboutLayout from '@/layouts/About'; 4 + import BlogLayout from '@/layouts/Blog'; 5 + import DefaultLayout from '@/layouts/Default'; 6 + import DownloadLayout from '@/layouts/Download'; 7 + import HomeLayout from '@/layouts/Home'; 8 + import LearnLayout from '@/layouts/Learn'; 9 + import PostLayout from '@/layouts/Post'; 10 + import SearchLayout from '@/layouts/Search'; 11 + import type { Layouts } from '@/types'; 21 12 22 - /** @deprecated these should be removed with the website redesin */ 23 - const legacyLayouts = { 24 - 'docs.hbs': LegacyDocsLayout, 25 - 'about.hbs': LegacyAboutLayout, 26 - 'blog-category.hbs': LegacyBlogCategoryLayout, 27 - 'blog-post.hbs': LegacyBlogPostLayout, 28 - 'download.hbs': LegacyDownloadLayout, 29 - 'index.hbs': LegacyIndexLayout, 30 - 'learn.hbs': LegacyLearnLayout, 31 - 'page.hbs': LegacyDefaultLayout, 32 - } satisfies Record<LegacyLayouts, FC>; 33 - 34 - /** all the currently available layouts from website redesign */ 35 - const redesignLayouts = { 13 + const layouts = { 36 14 'about.hbs': AboutLayout, 37 15 'home.hbs': HomeLayout, 38 16 'learn.hbs': LearnLayout, ··· 43 21 'download.hbs': DownloadLayout, 44 22 } satisfies Record<Layouts, FC>; 45 23 46 - type WithLayout<L = Layouts | LegacyLayouts> = PropsWithChildren<{ layout: L }>; 24 + type WithLayouProps<L = Layouts> = PropsWithChildren<{ layout: L }>; 47 25 48 - const WithRedesign: FC<WithLayout<Layouts>> = ({ layout, children }) => { 49 - const LayoutComponent = redesignLayouts[layout] ?? DefaultLayout; 50 - 51 - return <LayoutComponent>{children}</LayoutComponent>; 52 - }; 53 - 54 - /** @deprecated method to be removed once website redesign is finished */ 55 - const WithLegacy: FC<WithLayout<LegacyLayouts>> = ({ layout, children }) => { 56 - const LayoutComponent = legacyLayouts[layout] ?? LegacyDefaultLayout; 26 + const WithLayout: FC<WithLayouProps<Layouts>> = ({ layout, children }) => { 27 + const LayoutComponent = layouts[layout] ?? DefaultLayout; 57 28 58 29 return <LayoutComponent>{children}</LayoutComponent>; 59 30 }; 60 31 61 - // Decides which Layout Connector to use based on the Environment 62 - // @todo: This should be removed once we switch to Redesign 63 - export default ENABLE_WEBSITE_REDESIGN ? WithRedesign : WithLegacy; 32 + export default WithLayout;
+2
hooks/react-client/useBottomScrollListener.ts
··· 29 29 30 30 useEffect(() => { 31 31 window.addEventListener('scroll', handleScroll, { passive: true }); 32 + 32 33 return () => window.removeEventListener('scroll', handleScroll); 34 + // eslint-disable-next-line react-hooks/exhaustive-deps 33 35 }, []); 34 36 35 37 return bottomReached;
+1 -1
hooks/react-client/useKeyboardCommands.ts
··· 30 30 }); 31 31 32 32 return () => document.removeEventListener('keydown', () => {}); 33 - }, []); 33 + }, [fn]); 34 34 }; 35 35 36 36 export default useKeyboardCommands;
+1 -1
i18n/locales/en.json
··· 286 286 "platform": "Platform" 287 287 }, 288 288 "codeBox": { 289 - "communityWarning": "Package Managers and their installation scripts are not maintained by the Node.js project.s" 289 + "communityWarning": "Package managers and their installation scripts are not maintained by the Node.js project." 290 290 } 291 291 } 292 292 },
-12
layouts/AboutLayout.tsx
··· 1 - import type { FC, PropsWithChildren } from 'react'; 2 - 3 - import SideNavigation from '@/components/SideNavigation'; 4 - 5 - const AboutLayout: FC<PropsWithChildren> = ({ children }) => ( 6 - <div className="has-side-nav container"> 7 - <SideNavigation navigationKeys={['about', 'getInvolved']} /> 8 - <article dir="auto">{children}</article> 9 - </div> 10 - ); 11 - 12 - export default AboutLayout;
-17
layouts/BaseLayout.tsx
··· 1 - import type { FC, PropsWithChildren } from 'react'; 2 - 3 - import Footer from '@/components/Footer'; 4 - import Header from '@/components/Header'; 5 - import TopNavigation from '@/components/TopNavigation'; 6 - 7 - const BaseLayout: FC<PropsWithChildren> = ({ children }) => ( 8 - <> 9 - <Header> 10 - <TopNavigation /> 11 - </Header> 12 - <main id="main">{children}</main> 13 - <Footer /> 14 - </> 15 - ); 16 - 17 - export default BaseLayout;
-56
layouts/BlogCategoryLayout.tsx
··· 1 - import { getTranslations } from 'next-intl/server'; 2 - import type { FC } from 'react'; 3 - 4 - import { getClientContext } from '@/client-context'; 5 - import FormattedTime from '@/components/Common/FormattedTime'; 6 - import Link from '@/components/Link'; 7 - import Pagination from '@/components/Pagination'; 8 - import getBlogData from '@/next-data/blogData'; 9 - 10 - const getCategoryData = async (pathname: string) => { 11 - // pathname format can either be: /en/blog/{category} 12 - // or /en/blog/{category}/page/{page} 13 - // hence we attempt to interpolate the full /en/blog/{category}/page/{page} 14 - // and in case of course no page argument is provided we define it to 1 15 - // note that malformed routes can't happen as they are all statically generated 16 - const [, , category = 'all', , page = 1] = pathname.split('/'); 17 - 18 - const { posts, pagination } = await getBlogData(category, Number(page)); 19 - 20 - return { posts, category, pagination }; 21 - }; 22 - 23 - // This is a React Async Server Component 24 - // Note that Hooks cannot be used in a RSC async component 25 - // Async Components do not get re-rendered at all. 26 - const BlogCategoryLayout: FC = async () => { 27 - const { pathname } = getClientContext(); 28 - 29 - const t = await getTranslations(); 30 - 31 - const { posts, pagination, category } = await getCategoryData(pathname); 32 - 33 - return ( 34 - <div className="container" dir="auto"> 35 - <h2 style={{ textTransform: 'capitalize' }}> 36 - {t('layouts.blogIndex.categoryName', { 37 - category: category.replace('year-', ''), 38 - })} 39 - </h2> 40 - 41 - <ul className="blog-index"> 42 - {posts.map(({ slug, date, title }) => ( 43 - <li key={slug}> 44 - <FormattedTime date={date} /> 45 - 46 - <Link href={slug}>{title}</Link> 47 - </li> 48 - ))} 49 - </ul> 50 - 51 - <Pagination category={category} {...pagination} /> 52 - </div> 53 - ); 54 - }; 55 - 56 - export default BlogCategoryLayout;
-32
layouts/BlogPostLayout.tsx
··· 1 - import { useTranslations } from 'next-intl'; 2 - import type { FC, PropsWithChildren } from 'react'; 3 - 4 - import FormattedTime from '@/components/Common/FormattedTime'; 5 - import { useClientContext } from '@/hooks/server'; 6 - 7 - const BlogPostLayout: FC<PropsWithChildren> = ({ children }) => { 8 - const t = useTranslations(); 9 - 10 - const { 11 - frontmatter: { title, author, date }, 12 - } = useClientContext(); 13 - 14 - return ( 15 - <div className="container"> 16 - <article dir="auto"> 17 - <div className="blogpost-header"> 18 - <h1>{title}</h1> 19 - <span className="blogpost-meta"> 20 - {t('layouts.blogPost.author.byLine', { author: author || null })} 21 - 22 - <FormattedTime date={date} /> 23 - </span> 24 - </div> 25 - 26 - {children} 27 - </article> 28 - </div> 29 - ); 30 - }; 31 - 32 - export default BlogPostLayout;
-7
layouts/DefaultLayout.tsx
··· 1 - import type { FC, PropsWithChildren } from 'react'; 2 - 3 - const DefaultLayout: FC<PropsWithChildren> = ({ children }) => ( 4 - <div className="container">{children}</div> 5 - ); 6 - 7 - export default DefaultLayout;
-9
layouts/DocsLayout.tsx
··· 1 - import type { FC, PropsWithChildren } from 'react'; 2 - 3 - const DocsLayout: FC<PropsWithChildren> = ({ children }) => ( 4 - <div className="has-side-nav container"> 5 - <article dir="auto">{children}</article> 6 - </div> 7 - ); 8 - 9 - export default DocsLayout;
-51
layouts/DownloadLayout.tsx
··· 1 - import type { FC, PropsWithChildren } from 'react'; 2 - 3 - import PrimaryDownloadMatrix from '@/components/Downloads/PrimaryDownloadMatrix'; 4 - import SecondaryDownloadMatrix from '@/components/Downloads/SecondaryDownloadMatrix'; 5 - import WithNodeRelease from '@/components/withNodeRelease'; 6 - import { useClientContext } from '@/hooks/server'; 7 - 8 - const DownloadLayout: FC<PropsWithChildren> = ({ children }) => { 9 - const { 10 - frontmatter: { downloads }, 11 - pathname, 12 - } = useClientContext(); 13 - 14 - const isCurrentReleasePage = pathname.includes('/current'); 15 - 16 - return ( 17 - <div className="container"> 18 - <article dir="auto"> 19 - <div className="download-header"> 20 - <h1>{downloads.headline}</h1> 21 - </div> 22 - 23 - {children} 24 - 25 - {isCurrentReleasePage && ( 26 - <WithNodeRelease status="Current"> 27 - {({ release }) => ( 28 - <> 29 - <PrimaryDownloadMatrix {...release} /> 30 - <SecondaryDownloadMatrix {...release} /> 31 - </> 32 - )} 33 - </WithNodeRelease> 34 - )} 35 - 36 - {isCurrentReleasePage || ( 37 - <WithNodeRelease status={['Active LTS', 'Maintenance LTS']}> 38 - {({ release }) => ( 39 - <> 40 - <PrimaryDownloadMatrix {...release} /> 41 - <SecondaryDownloadMatrix {...release} /> 42 - </> 43 - )} 44 - </WithNodeRelease> 45 - )} 46 - </article> 47 - </div> 48 - ); 49 - }; 50 - 51 - export default DownloadLayout;
-9
layouts/IndexLayout.tsx
··· 1 - import type { FC, PropsWithChildren } from 'react'; 2 - 3 - const IndexLayout: FC<PropsWithChildren> = ({ children }) => ( 4 - <div className="container"> 5 - <div id="home-intro">{children}</div> 6 - </div> 7 - ); 8 - 9 - export default IndexLayout;
-12
layouts/LearnLayout.tsx
··· 1 - import type { FC, PropsWithChildren } from 'react'; 2 - 3 - import SideNavigation from '@/components/SideNavigation'; 4 - 5 - const LearnLayout: FC<PropsWithChildren> = ({ children }) => ( 6 - <div className="has-side-nav container"> 7 - <SideNavigation navigationKeys={['learn']} /> 8 - <article dir="auto">{children}</article> 9 - </div> 10 - ); 11 - 12 - export default LearnLayout;
+1 -1
layouts/New/About.tsx layouts/About.tsx
··· 4 4 import WithMetaBar from '@/components/withMetaBar'; 5 5 import WithNavBar from '@/components/withNavBar'; 6 6 import WithSidebar from '@/components/withSidebar'; 7 - import ArticleLayout from '@/layouts/New/Article'; 7 + import ArticleLayout from '@/layouts/Article'; 8 8 9 9 const AboutLayout: FC<PropsWithChildren> = ({ children }) => ( 10 10 <>
layouts/New/Article.tsx layouts/Article.tsx
layouts/New/Base.tsx layouts/Base.tsx
layouts/New/Blog.tsx layouts/Blog.tsx
layouts/New/Centered.tsx layouts/Centered.tsx
layouts/New/Content.tsx layouts/Content.tsx
+1 -1
layouts/New/Default.tsx layouts/Default.tsx
··· 3 3 import WithFooter from '@/components/withFooter'; 4 4 import WithNavBar from '@/components/withNavBar'; 5 5 import WithSidebar from '@/components/withSidebar'; 6 - import ArticleLayout from '@/layouts/New/Article'; 6 + import ArticleLayout from '@/layouts/Article'; 7 7 8 8 const DefaultLayout: FC<PropsWithChildren> = ({ children }) => ( 9 9 <>
layouts/New/Download.tsx layouts/Download.tsx
+1 -1
layouts/New/Home.tsx layouts/Home.tsx
··· 1 1 import type { FC, PropsWithChildren } from 'react'; 2 2 3 - import CenteredLayout from '@/layouts/New/Centered'; 3 + import CenteredLayout from '@/layouts/Centered'; 4 4 5 5 import styles from './layouts.module.css'; 6 6
+1 -1
layouts/New/Learn.tsx layouts/Learn.tsx
··· 5 5 import WithNavBar from '@/components/withNavBar'; 6 6 import WithProgressionSidebar from '@/components/withProgressionSidebar'; 7 7 import WithSidebarCrossLinks from '@/components/withSidebarCrossLinks'; 8 - import ArticleLayout from '@/layouts/New/Article'; 8 + import ArticleLayout from '@/layouts/Article'; 9 9 10 10 const LearnLayout: FC<PropsWithChildren> = ({ children }) => ( 11 11 <>
+1 -1
layouts/New/Post.tsx layouts/Post.tsx
··· 7 7 import WithMetaBar from '@/components/withMetaBar'; 8 8 import WithNavBar from '@/components/withNavBar'; 9 9 import { useClientContext } from '@/hooks/react-server'; 10 - import ContentLayout from '@/layouts/New/Content'; 10 + import ContentLayout from '@/layouts/Content'; 11 11 import { 12 12 mapAuthorToCardAuthors, 13 13 mapBlogCategoryToPreviewType,
layouts/New/Search.tsx layouts/Search.tsx
layouts/New/layouts.module.css layouts/layouts.module.css
+1 -29
next.config.mjs
··· 1 1 'use strict'; 2 2 3 - import { resolve } from 'node:path'; 4 - 5 3 import { withSentryConfig } from '@sentry/nextjs'; 6 4 import withNextIntl from 'next-intl/plugin'; 7 5 8 - import { 9 - BASE_PATH, 10 - ENABLE_STATIC_EXPORT, 11 - ENABLE_WEBSITE_REDESIGN, 12 - } from './next.constants.mjs'; 6 + import { BASE_PATH, ENABLE_STATIC_EXPORT } from './next.constants.mjs'; 13 7 import { redirects, rewrites } from './next.rewrites.mjs'; 14 8 import { 15 9 SENTRY_DSN, ··· 65 59 // Tree-shakes modules from Sentry Bundle 66 60 config.plugins.push(new webpack.DefinePlugin(SENTRY_EXTENSIONS)); 67 61 68 - // This allows us to customise our global styles on build-tim,e 69 - // based on if we're running the Website Redesign or not 70 - config.resolve.alias = { 71 - ...config.resolve.alias, 72 - // @deprecated remove when website redesign is done 73 - globalStyles$: resolve( 74 - ENABLE_WEBSITE_REDESIGN 75 - ? './styles/new/index.css' 76 - : './styles/old/index.css' 77 - ), 78 - }; 79 - 80 62 return config; 81 63 }, 82 64 experimental: { 83 - turbo: { 84 - resolveAlias: { 85 - // This allows us to customise our global styles on build-tim,e 86 - // based on if we're running the Website Redesign or not 87 - // @deprecated remove when website redesign is done 88 - globalStyles: ENABLE_WEBSITE_REDESIGN 89 - ? './styles/new/index.css' 90 - : './styles/old/index.css', 91 - }, 92 - }, 93 65 // Some of our static pages from `getStaticProps` have a lot of data 94 66 // since we pass the fully-compiled MDX page from `MDXRemote` through 95 67 // a page's static props.
+1 -12
next.constants.mjs
··· 37 37 process.env.NEXT_PUBLIC_STATIC_EXPORT === true; 38 38 39 39 /** 40 - * This is used for enabling the New Website Redesign Layouts 41 - * 42 - * Note that this is a manual Environment Variable defined by us if necessary. 43 - */ 44 - export const ENABLE_WEBSITE_REDESIGN = 45 - process.env.NEXT_PUBLIC_ENABLE_REDESIGN === 'true' || 46 - process.env.NEXT_PUBLIC_ENABLE_REDESIGN === true; 47 - 48 - /** 49 40 * This is used for any place that requires the full canonical URL path for the Node.js Website (and its deployment), such as for example, the Node.js RSS Feed. 50 41 * 51 42 * This variable can either come from the Vercel Deployment as `NEXT_PUBLIC_VERCEL_URL` or from the `NEXT_PUBLIC_BASE_URL` Environment Variable that is manually defined ··· 110 101 111 102 /** 112 103 * This defines how many blog posts each pagination page should have 113 - * 114 - * @todo: update the value when moving to website redesign 115 104 */ 116 - export const BLOG_POSTS_PER_PAGE = ENABLE_WEBSITE_REDESIGN ? 6 : 20; 105 + export const BLOG_POSTS_PER_PAGE = 6; 117 106 118 107 /** 119 108 * The `localStorage` key to store the theme choice of `next-themes`
-3
next.dynamic.constants.mjs
··· 18 18 // This is used to ignore all blog routes except for the English language 19 19 ({ locale, pathname }) => 20 20 locale !== defaultLocale.code && /^blog/.test(pathname), 21 - // Do not statically build the redesign pages on the static export 22 - // @deprecated this should be removed once we remove the legacy website 23 - ({ pathname }) => /^new-design/.test(pathname), 24 21 ]; 25 22 26 23 /**
+1 -10
next.fonts.ts
··· 1 - import { Source_Sans_3, Open_Sans, IBM_Plex_Mono } from 'next/font/google'; 2 - 3 - // This configures the Next.js Font for Source Sans 4 - // We then export a variable and class name to be used 5 - // within Tailwind (tailwind.config.ts) and Storybook (preview.js) 6 - export const SOURCE_SANS = Source_Sans_3({ 7 - weight: ['400', '600'], 8 - display: 'fallback', 9 - subsets: ['latin'], 10 - }); 1 + import { Open_Sans, IBM_Plex_Mono } from 'next/font/google'; 11 2 12 3 // This configures the Next.js Font for Open Sans 13 4 // We then export a variable and class name to be used
+2 -10
next.mdx.use.mjs
··· 18 18 import SourceButton from './components/Downloads/Release/SourceButton'; 19 19 import VerifyingBinariesLink from './components/Downloads/Release/VerifyingBinariesLink'; 20 20 import VersionDropdown from './components/Downloads/Release/VersionDropdown'; 21 - import HomeDownloadButton from './components/Home/HomeDownloadButton'; 22 21 import Link from './components/Link'; 23 22 import UpcomingMeetings from './components/MDX/Calendar/UpcomingMeetings'; 24 23 import MDXCodeBox from './components/MDX/CodeBox'; ··· 27 26 import WithBadge from './components/withBadge'; 28 27 import WithBanner from './components/withBanner'; 29 28 import WithNodeRelease from './components/withNodeRelease'; 30 - import { ENABLE_WEBSITE_REDESIGN } from './next.constants.mjs'; 31 29 32 30 /** 33 31 * A full list of React Components that we want to pass through to MDX ··· 35 33 * @satisfies {import('mdx/types').MDXComponents} 36 34 */ 37 35 export const mdxComponents = { 38 - // Legacy Component 39 - HomeDownloadButton: HomeDownloadButton, 40 - // Legacy Component 41 36 DownloadReleasesTable: DownloadReleasesTable, 42 37 // HOC for getting Node.js Release Metadata 43 38 WithNodeRelease: WithNodeRelease, ··· 97 92 export const htmlComponents = { 98 93 // Renders a Link Component for `a` tags 99 94 a: Link, 100 - // @deprecated once the website redesign happens 101 - // switch to only use the Blockquote Component 102 - blockquote: ENABLE_WEBSITE_REDESIGN 103 - ? Blockquote 104 - : ({ children }) => <div className="highlight-box">{children}</div>, 95 + // Renders a Blockquote Component for `blockquote` tags 96 + blockquote: Blockquote, 105 97 // Renders a CodeBox Component for `pre` tags 106 98 pre: MDXCodeBox, 107 99 };
-24
next.rewrites.mjs
··· 1 1 'use strict'; 2 2 3 - import { ENABLE_WEBSITE_REDESIGN } from './next.constants.mjs'; 4 3 import { siteRedirects } from './next.json.mjs'; 5 4 import { availableLocaleCodes } from './next.locales.mjs'; 6 5 ··· 44 43 destination, 45 44 }) 46 45 ); 47 - 48 - // This allows us to remap legacy website URLs to the temporary redesign ones 49 - // @todo: remove this once website redesign is done 50 - if (ENABLE_WEBSITE_REDESIGN) { 51 - mappedRewrites.push( 52 - { 53 - source: localesMatch, 54 - destination: '/:locale/new-design', 55 - }, 56 - { 57 - source: '/:locale/download', 58 - destination: '/:locale/new-design/download', 59 - }, 60 - { 61 - source: '/:locale/download/:path', 62 - destination: '/:locale/new-design/download/:path', 63 - }, 64 - { 65 - source: '/:locale/download/:path/:version', 66 - destination: '/:locale/new-design/download/:path/:version', 67 - } 68 - ); 69 - } 70 46 71 47 return { afterFiles: mappedRewrites }; 72 48 };
-1
package.json
··· 17 17 "scripts": { 18 18 "scripts:release-post": "cross-env NODE_NO_WARNINGS=1 node scripts/release-post/index.mjs", 19 19 "serve": "cross-env NODE_NO_WARNINGS=1 next dev --turbo", 20 - "serve:redesign": "cross-env NEXT_PUBLIC_ENABLE_REDESIGN=true npm run serve", 21 20 "build": "cross-env NODE_NO_WARNINGS=1 next build", 22 21 "start": "cross-env NODE_NO_WARNINGS=1 next start", 23 22 "deploy": "cross-env NEXT_PUBLIC_STATIC_EXPORT=true npm run build",
+5 -1
pages/en/about/index.mdx
··· 4 4 --- 5 5 6 6 <div className="my-4 flex items-center justify-center"> 7 - <img src="/static/images/node-mascot.svg" className="w-[100px]" /> 7 + <img 8 + alt="Node.js mascot" 9 + src="/static/images/node-mascot.svg" 10 + className="w-[100px]" 11 + /> 8 12 </div> 9 13 10 14 ---
-34
pages/en/download/current.md
··· 1 - --- 2 - layout: download.hbs 3 - title: Download 4 - download: Download 5 - downloads: 6 - headline: Downloads 7 - lts: LTS 8 - current: Current 9 - tagline-current: Latest Features 10 - tagline-lts: Recommended For Most Users 11 - display-hint: Display downloads for 12 - intro: > 13 - Download the Node.js source code or a pre-built installer for your platform, and start developing today. 14 - currentVersion: Latest Current Version 15 - buildInstructions: Building Node.js from source on supported platforms 16 - WindowsInstaller: Windows Installer 17 - WindowsBinary: Windows Binary 18 - MacOSInstaller: macOS Installer 19 - MacOSBinary: macOS Binary 20 - LinuxBinaries: Linux Binaries 21 - SourceCode: Source Code 22 - additional: 23 - headline: Additional Platforms 24 - intro: > 25 - Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release. 26 - platform: Platform 27 - provider: Provider 28 - SmartOSBinaries: SmartOS Binaries 29 - DockerImage: Docker Image 30 - officialDockerImage: Official Node.js Docker Image 31 - LinuxPowerSystems: Linux on Power LE Systems 32 - LinuxSystemZ: Linux on System z 33 - AIXPowerSystems: AIX on Power Systems 34 - ---
-34
pages/en/download/index.md
··· 1 - --- 2 - layout: download.hbs 3 - title: Download 4 - download: Download 5 - downloads: 6 - headline: Downloads 7 - lts: LTS 8 - current: Current 9 - tagline-current: Latest Features 10 - tagline-lts: Recommended For Most Users 11 - display-hint: Display downloads for 12 - intro: > 13 - Download the Node.js source code or a pre-built installer for your platform, and start developing today. 14 - currentVersion: Latest LTS Version 15 - buildInstructions: Building Node.js from source on supported platforms 16 - WindowsInstaller: Windows Installer 17 - WindowsBinary: Windows Binary 18 - MacOSInstaller: macOS Installer 19 - MacOSBinary: macOS Binary 20 - LinuxBinaries: Linux Binaries 21 - SourceCode: Source Code 22 - additional: 23 - headline: Additional Platforms 24 - intro: > 25 - Members of the Node.js community maintain unofficial builds of Node.js for additional platforms. Note that such builds are not supported by the Node.js core team and may not yet be at the same build level as current Node.js release. 26 - platform: Platform 27 - provider: Provider 28 - SmartOSBinaries: SmartOS Binaries 29 - DockerImage: Docker Image 30 - officialDockerImage: Official Node.js Docker Image 31 - LinuxPowerSystems: Linux on Power LE Systems 32 - LinuxSystemZ: Linux on System z 33 - AIXPowerSystems: AIX on Power Systems 34 - ---
-410
pages/en/download/package-manager.md
··· 1 - --- 2 - layout: docs.hbs 3 - title: Installing Node.js via package manager 4 - --- 5 - 6 - # Installing Node.js via package manager 7 - 8 - **_Note:_** The packages on this page are maintained and supported by their respective packagers, **not** the Node.js core team. Please report any issues you encounter to the package maintainer. If it turns out your issue is a bug in Node.js itself, the maintainer will report the issue upstream. 9 - 10 - --- 11 - 12 - - [Alpine Linux](#alpine-linux) 13 - - [Android](#android) 14 - - [Arch Linux](#arch-linux) 15 - - [CentOS, Fedora and Red Hat Enterprise Linux](#centos-fedora-and-red-hat-enterprise-linux) 16 - - [Debian and Ubuntu based Linux distributions](#debian-and-ubuntu-based-linux-distributions) 17 - - [fnm](#fnm) 18 - - [FreeBSD](#freebsd) 19 - - [Gentoo](#gentoo) 20 - - [IBM i](#ibm-i) 21 - - [macOS](#macos) 22 - - [n](#n) 23 - - [NetBSD](#netbsd) 24 - - [Nodenv](#nodenv) 25 - - [nvm](#nvm) 26 - - [nvs](#nvs) 27 - - [OpenBSD](#openbsd) 28 - - [openSUSE and SLE](#opensuse-and-sle) 29 - - [SmartOS and illumos](#smartos-and-illumos) 30 - - [Snap](#snap) 31 - - [Solus](#solus) 32 - - [Void Linux](#void-linux) 33 - - [Windows](#windows-1) 34 - - [z/OS](#zos) 35 - 36 - --- 37 - 38 - ## Alpine Linux 39 - 40 - Node.js LTS and npm packages are available in the Main Repository. 41 - 42 - ```bash 43 - apk add nodejs npm 44 - ``` 45 - 46 - Node.js Current can be installed from the Community Repository. 47 - 48 - ```bash 49 - apk add nodejs-current 50 - ``` 51 - 52 - ## Android 53 - 54 - Android support is still experimental in Node.js, so precompiled binaries are not yet provided by Node.js developers. 55 - 56 - However, there are some third-party solutions. For example, [Termux](https://termux.com/) community provides terminal emulator and Linux environment for Android, as well as own package manager and [extensive collection](https://github.com/termux/termux-packages) of many precompiled applications. This command in Termux app will install the last available Node.js version: 57 - 58 - ```bash 59 - pkg install nodejs 60 - ``` 61 - 62 - Currently, Termux Node.js binaries are linked against `system-icu` (depending on `libicu` package). 63 - 64 - ## Arch Linux 65 - 66 - Node.js and npm packages are available in the Community Repository. 67 - 68 - ```bash 69 - pacman -S nodejs npm 70 - ``` 71 - 72 - ## CentOS, Fedora and Red Hat Enterprise Linux 73 - 74 - Node.js is available as a module called `nodejs` in CentOS/RHEL 8 and Fedora. 75 - 76 - ```bash 77 - dnf module install nodejs:<stream> 78 - ``` 79 - 80 - where `<stream>` corresponds to the major version of Node.js. 81 - To see a list of available streams: 82 - 83 - ```bash 84 - dnf module list nodejs 85 - ``` 86 - 87 - For example, to install Node.js 18: 88 - 89 - ```bash 90 - dnf module install nodejs:18/common 91 - ``` 92 - 93 - ### Alternatives 94 - 95 - These resources provide packages compatible with CentOS, Fedora, and RHEL. 96 - 97 - - [Node.js snaps](#snap) maintained and supported at https://github.com/nodejs/snap 98 - - [Node.js binary distributions](#debian-and-ubuntu-based-linux-distributions) maintained and supported by [NodeSource](https://github.com/nodesource/distributions) 99 - 100 - ## Debian and Ubuntu based Linux distributions 101 - 102 - [Node.js binary distributions](https://github.com/nodesource/distributions) are available from NodeSource. 103 - 104 - ### Alternatives 105 - 106 - Packages compatible with Debian and Ubuntu based Linux distributions are available via [Node.js snaps](#snap). 107 - 108 - ## fnm 109 - 110 - Fast and simple Node.js version manager built in Rust used to manage multiple released Node.js versions. It allows you to perform operations like install, uninstall, switch Node versions automatically based on the current directory, etc. 111 - To install fnm, use this [install script](https://github.com/Schniz/fnm#using-a-script-macoslinux). 112 - 113 - fnm has cross-platform support (macOS, Windows, Linux) & all popular shells (Bash, Zsh, Fish, PowerShell, Windows Command Line Prompt). 114 - fnm is built with speed in mind and compatibility support for `.node-version` and `.nvmrc` files. 115 - 116 - ## FreeBSD 117 - 118 - The most recent release of Node.js is available via the [www/node](https://www.freshports.org/www/node) port. 119 - 120 - Install a binary package via [pkg](https://www.freebsd.org/cgi/man.cgi?pkg): 121 - 122 - ```bash 123 - pkg install node 124 - ``` 125 - 126 - Or compile it on your own using [ports](https://www.freebsd.org/cgi/man.cgi?ports): 127 - 128 - ```bash 129 - cd /usr/ports/www/node && make install 130 - ``` 131 - 132 - ## Gentoo 133 - 134 - Node.js is available in the portage tree. 135 - 136 - ```bash 137 - emerge nodejs 138 - ``` 139 - 140 - ## IBM i 141 - 142 - LTS versions of Node.js are available from IBM, and are available via [the 'yum' package manager](https://ibm.biz/ibmi-rpms). The package name is `nodejs` followed by the major version number (for instance, `nodejs18`, `nodejs20` etc) 143 - 144 - To install Node.js 20.x from the command line, run the following as a user with \*ALLOBJ special authority: 145 - 146 - ```bash 147 - yum install nodejs20 148 - ``` 149 - 150 - Node.js can also be installed with the IBM i Access Client Solutions product. See [this support document](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) for more details 151 - 152 - ## macOS 153 - 154 - Download the [macOS Installer](/#home-downloadhead) directly from the [nodejs.org](https://nodejs.org/) web site. 155 - 156 - _If you want to download the package with bash:_ 157 - 158 - ```bash 159 - curl "https://nodejs.org/dist/latest/$(curl -s https://nodejs.org/dist/latest/ | grep "pkg" | cut -d'"' -f 2)" -o "$HOME/Downloads/node-latest.pkg" && sudo installer -store -pkg "$HOME/Downloads/node-latest.pkg" -target "/" 160 - ``` 161 - 162 - ### Alternatives 163 - 164 - Using **[Homebrew](https://brew.sh/)**: 165 - 166 - ```bash 167 - brew install node 168 - ``` 169 - 170 - Using **[MacPorts](https://www.macports.org/)**: 171 - 172 - ```bash 173 - port install nodejs<major version> 174 - 175 - # Example 176 - port install nodejs7 177 - ``` 178 - 179 - Using **[pkgsrc](https://pkgsrc.joyent.com/install-on-macos/)**: 180 - 181 - Install the binary package: 182 - 183 - ```bash 184 - pkgin -y install nodejs 185 - ``` 186 - 187 - Or build manually from pkgsrc: 188 - 189 - ```bash 190 - cd pkgsrc/lang/nodejs && bmake install 191 - ``` 192 - 193 - ## n 194 - 195 - `n` is a simple to use Node.js version manager for Mac and Linux. Specify the target version to install using a rich syntax, 196 - or select from a menu of previously downloaded versions. The versions are installed system-wide or user-wide, and for more 197 - targeted use you can run a version directly from the cached downloads. 198 - 199 - See the [homepage](https://github.com/tj/n) for install methods (bootstrap, npm, Homebrew, third-party), and all the usage details. 200 - 201 - If you already have `npm` then installing `n` and then the newest LTS `node` version is as simple as: 202 - 203 - ``` 204 - npm install -g n 205 - n lts 206 - ``` 207 - 208 - ## NetBSD 209 - 210 - Node.js is available in the pkgsrc tree: 211 - 212 - ```bash 213 - cd /usr/pkgsrc/lang/nodejs && make install 214 - ``` 215 - 216 - Or install a binary package (if available for your platform) using pkgin: 217 - 218 - ```bash 219 - pkgin -y install nodejs 220 - ``` 221 - 222 - ## Nodenv 223 - 224 - `nodenv` is a lightweight node version manager, similar to `nvm`. It's simple and predictable. A rich plugin ecosystem lets you tailor it to suit your needs. Use `nodenv` to pick a Node version for your application and guarantee that your development environment matches production. 225 - 226 - Nodenv installation instructions are maintained [on its Github page](https://github.com/nodenv/nodenv#installation). Please visit that page to ensure you're following the latest version of the installation steps. 227 - 228 - ## nvm 229 - 230 - Node Version Manager is a bash script used to manage multiple released Node.js versions. It allows 231 - you to perform operations like install, uninstall, switch version, etc. 232 - To install nvm, use this [install script](https://github.com/nvm-sh/nvm#install--update-script). 233 - 234 - On Unix / OS X systems Node.js built from source can be installed using 235 - [nvm](https://github.com/creationix/nvm) by installing into the location that nvm expects: 236 - 237 - ```bash 238 - env VERSION=`python tools/getnodeversion.py` make install DESTDIR=`nvm_version_path v$VERSION` PREFIX="" 239 - ``` 240 - 241 - After this you can use `nvm` to switch between released versions and versions 242 - built from source. 243 - For example, if the version of Node.js is v8.0.0-pre: 244 - 245 - ```bash 246 - nvm use 8 247 - ``` 248 - 249 - Once the official release is out you will want to uninstall the version built 250 - from source: 251 - 252 - ```bash 253 - nvm uninstall 8 254 - ``` 255 - 256 - ## nvs 257 - 258 - #### Windows 259 - 260 - The `nvs` version manager is cross-platform and can be used on Windows, macOS, and Unix-like systems 261 - 262 - To install `nvs` on Windows go to the [release page](https://github.com/jasongin/nvs/releases) here and download the MSI installer file of the latest release. 263 - 264 - You can also use `chocolatey` to install it: 265 - 266 - ```bash 267 - choco install nvs 268 - ``` 269 - 270 - #### macOS,UnixLike 271 - 272 - You can find the documentation regarding the installation steps of `nvs` in macOS/Unix-like systems [here](https://github.com/jasongin/nvs/blob/master/doc/SETUP.md#mac-linux) 273 - 274 - #### Usage 275 - 276 - After this you can use `nvs` to switch between different versions of node. 277 - 278 - To add the latest version of node: 279 - 280 - ```bash 281 - nvs add latest 282 - ``` 283 - 284 - Or to add the latest LTS version of node: 285 - 286 - ```bash 287 - nvs add lts 288 - ``` 289 - 290 - Then run the `nvs use` command to add a version of node to your `PATH` for the current shell: 291 - 292 - ```bash 293 - $ nvs use lts 294 - PATH -= %LOCALAPPDATA%\nvs\default 295 - PATH += %LOCALAPPDATA%\nvs\node\14.17.0\x64 296 - ``` 297 - 298 - To add it to `PATH` permanently, use `nvs link`: 299 - 300 - ```bash 301 - nvs link lts 302 - ``` 303 - 304 - ## OpenBSD 305 - 306 - Node.js is available through the ports system. 307 - 308 - ```bash 309 - /usr/ports/lang/node 310 - ``` 311 - 312 - Using [pkg_add](https://man.openbsd.org/OpenBSD-current/man1/pkg_add.1) on OpenBSD: 313 - 314 - ```bash 315 - pkg_add node 316 - ``` 317 - 318 - ## openSUSE and SLE 319 - 320 - Node.js is available in the main repositories under the following packages: 321 - 322 - - **openSUSE Leap 15.2**: `nodejs10`, `nodejs12`, `nodejs14` 323 - - **openSUSE Tumbleweed**: `nodejs20` 324 - - **SUSE Linux Enterprise Server (SLES) 12**: `nodejs10`, `nodejs12`, and `nodejs14` 325 - (The "Web and Scripting Module" must be [enabled](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/12-SP5/#intro-modulesExtensionsRelated).) 326 - - **SUSE Linux Enterprise Server (SLES) 15 SP2**: `nodejs10`, `nodejs12`, and `nodejs14` 327 - (The "Web and Scripting Module" must be [enabled](https://www.suse.com/releasenotes/x86_64/SUSE-SLES/15/#Intro.Module).) 328 - 329 - For example, to install Node.js 14.x on openSUSE Leap 15.2, run the following as root: 330 - 331 - ```bash 332 - zypper install nodejs14 333 - ``` 334 - 335 - Different major versions of Node can be installed and used concurrently. 336 - 337 - ## SmartOS and illumos 338 - 339 - SmartOS images come with pkgsrc pre-installed. On other illumos distributions, first install **[pkgsrc](https://pkgsrc.joyent.com/install-on-illumos/)**, then you may install the binary package as normal: 340 - 341 - ```bash 342 - pkgin -y install nodejs 343 - ``` 344 - 345 - Or build manually from pkgsrc: 346 - 347 - ```bash 348 - cd pkgsrc/lang/nodejs && bmake install 349 - ``` 350 - 351 - ## Snap 352 - 353 - [Node.js snaps](https://github.com/nodejs/snap) are available as [`node`](https://snapcraft.io/node) on the Snap store. 354 - 355 - ## Solus 356 - 357 - Solus provides Node.js in its main repository. 358 - 359 - ```bash 360 - sudo eopkg install nodejs 361 - ``` 362 - 363 - ## Void Linux 364 - 365 - Void Linux ships Node.js stable in the main repository. 366 - 367 - ```bash 368 - xbps-install -Sy nodejs 369 - ``` 370 - 371 - ## Windows 372 - 373 - Download the [Windows Installer](/#home-downloadhead) directly from the [nodejs.org](https://nodejs.org/) web site. 374 - 375 - ### Alternatives 376 - 377 - Using **[Winget](https://aka.ms/winget-cli)**: 378 - 379 - ```bash 380 - winget install OpenJS.NodeJS 381 - # or for LTS 382 - winget install OpenJS.NodeJS.LTS 383 - ``` 384 - 385 - After running one of the two commands above, it may be necessary to restart the 386 - terminal emulator before the `node` CLI command becomes available. 387 - 388 - Using **[Chocolatey](https://chocolatey.org/)**: 389 - 390 - ```bash 391 - cinst nodejs 392 - # or for full install with npm 393 - cinst nodejs.install 394 - ``` 395 - 396 - Using **[Scoop](https://scoop.sh/)**: 397 - 398 - ```bash 399 - scoop install nodejs 400 - # or for LTS 401 - scoop install nodejs-lts 402 - ``` 403 - 404 - ## z/OS 405 - 406 - IBM&reg; SDK for Node.js - z/OS&reg; is available in two installation formats, 407 - SMP/E and PAX. Select the installation format that applies to you: 408 - 409 - - [Installing and configuring SMP/E edition of Node.js on z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-smpe-edition) 410 - - [Installing and configuring PAX edition of Node.js on z/OS](https://www.ibm.com/docs/en/sdk-nodejs-zos/14.0?topic=configuring-installing-pax-edition)
+109 -11
pages/en/index.mdx
··· 1 1 --- 2 - layout: index.hbs 2 + title: Run JavaScript Everywhere 3 + layout: home.hbs 3 4 --- 4 5 5 - Node.js® is an open-source, cross-platform JavaScript runtime environment. 6 + <section> 7 + <WithBadge section="index" /> 6 8 7 - <WithBanner section="index" /> 9 + <div> 10 + <h1 className="special">Run JavaScript Everywhere</h1> 8 11 9 - <h2>Download Node.js®</h2> 12 + Node.js® is a free, open-source, cross-platform JavaScript runtime 13 + environment that lets developers create servers, web apps, 14 + command line tools and scripts. 10 15 11 - <WithNodeRelease status={['Active LTS', 'Maintenance LTS']}> 12 - {({ release }) => <HomeDownloadButton {...release} />} 13 - </WithNodeRelease> 16 + </div> 14 17 15 - <WithNodeRelease status="Current"> 16 - {({ release }) => <HomeDownloadButton {...release} />} 17 - </WithNodeRelease> 18 + <div> 19 + <WithNodeRelease status={['Active LTS', 'Maintenance LTS']}> 20 + {({ release }) => ( 21 + <> 22 + <DownloadButton release={release}>Download Node.js (LTS)</DownloadButton> 23 + <small> 24 + Downloads Node.js <b>{release.versionWithPrefix}</b> 25 + <sup title="Downloads a Node.js installer for your current platform">1</sup> with long-term support. 26 + Node.js can also be installed via <a href="/download/package-manager">package managers</a>. 27 + </small> 28 + </> 29 + )} 30 + </WithNodeRelease> 31 + <WithNodeRelease status="Current"> 32 + {({ release }) => ( 33 + <small> 34 + Want new features sooner? 35 + Get <b>Node.js <DownloadLink release={release}>{release.versionWithPrefix}</DownloadLink></b> 36 + <sup title="Downloads a Node.js installer for your current platform">1</sup> instead. 37 + </small> 38 + )} 39 + </WithNodeRelease> 40 + </div> 41 + </section> 18 42 19 - For information about supported releases, see the [release schedule](/about/previous-releases). 43 + <section> 44 + <div> 45 + ```js displayName="Create an HTTP Server" 46 + import { createServer } from 'node:http'; 47 + 48 + const server = createServer((req, res) => { 49 + res.writeHead(200, { 'Content-Type': 'text/plain' }); 50 + res.end('Hello World!\n'); 51 + }); 52 + 53 + // starts a simple http server locally on port 3000 54 + server.listen(3000, '127.0.0.1', () => { 55 + console.log('Listening on 127.0.0.1:3000'); 56 + }); 57 + ``` 58 + 59 + ```js displayName="Write Tests" 60 + import assert from 'node:assert'; 61 + import test from 'node:test'; 62 + 63 + test('that 1 is equal 1', () => { 64 + assert.strictEqual(1, 1); 65 + }); 66 + 67 + test('that throws as 1 is not equal 2', () => { 68 + // throws an exception because 1 != 2 69 + assert.strictEqual(1, 2); 70 + }); 71 + ``` 72 + 73 + ```js displayName="Read and Hash a File" 74 + import { createHash } from 'node:crypto'; 75 + import { readFile } from 'node:fs/promises'; 76 + 77 + const hasher = createHash('sha1'); 78 + const fileContent = await readFile('./package.json'); 79 + 80 + hasher.setEncoding('hex'); 81 + hasher.write(fileContent); 82 + hasher.end(); 83 + 84 + const fileHash = hasher.read(); 85 + ``` 86 + 87 + ```js displayName="Read Streams" 88 + import { createReadStream, createWriteStream } from 'node:fs'; 89 + 90 + const res = await fetch('https://nodejs.org/dist/index.json'); 91 + const json = await res.json(); // yields a json object 92 + 93 + const readableStream = createReadStream('./package.json'); 94 + const writableStream = createWriteStream('./package2.json'); 95 + 96 + readableStream.setEncoding('utf8'); 97 + 98 + readableStream.on('data', chunk => writableStream.write(chunk)); 99 + ``` 100 + 101 + ```js displayName="Work with Threads" 102 + import { Worker, isMainThread, 103 + workerData, parentPort } from 'node:worker_threads'; 104 + 105 + if (isMainThread) { 106 + const data = 'some data'; 107 + const worker = new Worker(import.meta.filename, { workerData: data }); 108 + worker.on('message', msg => console.log('Reply from Thread:', msg)); 109 + } else { 110 + const source = workerData; 111 + parentPort.postMessage(btoa(source.toUpperCase())); 112 + } 113 + ``` 114 + 115 + </div> 116 + Learn more what Node.js is able to offer with our [Learning materials](/learn). 117 + </section>
pages/en/new-design/download/current.mdx pages/en/download/current.mdx
pages/en/new-design/download/index.mdx pages/en/download/index.mdx
+3 -3
pages/en/new-design/download/package-manager/all.md pages/en/download/package-manager/all.md
··· 139 139 140 140 ## IBM i 141 141 142 - LTS versions of Node.js are available from IBM, and are available via [the 'yum' package manager](https://ibm.biz/ibmi-rpms). The package name is `nodejs` followed by the major version number (for instance, `nodejs12`, `nodejs14` etc) 142 + LTS versions of Node.js are available from IBM, and are available via [the 'yum' package manager](https://ibm.biz/ibmi-rpms). The package name is `nodejs` followed by the major version number (for instance, `nodejs18`, `nodejs20` etc) 143 143 144 - To install Node.js 14.x from the command line, run the following as a user with \*ALLOBJ special authority: 144 + To install Node.js 20.x from the command line, run the following as a user with \*ALLOBJ special authority: 145 145 146 146 ```bash 147 - yum install nodejs14 147 + yum install nodejs20 148 148 ``` 149 149 150 150 Node.js can also be installed with the IBM i Access Client Solutions product. See [this support document](http://www-01.ibm.com/support/docview.wss?uid=nas8N1022619) for more details
pages/en/new-design/download/package-manager/current.mdx pages/en/download/package-manager/current.mdx
pages/en/new-design/download/package-manager/index.mdx pages/en/download/package-manager/index.mdx
pages/en/new-design/download/prebuilt-binaries/current.mdx pages/en/download/prebuilt-binaries/current.mdx
pages/en/new-design/download/prebuilt-binaries/index.mdx pages/en/download/prebuilt-binaries/index.mdx
pages/en/new-design/download/source-code/current.mdx pages/en/download/source-code/current.mdx
pages/en/new-design/download/source-code/index.mdx pages/en/download/source-code/index.mdx
-117
pages/en/new-design/index.mdx
··· 1 - --- 2 - title: Run JavaScript Everywhere 3 - layout: home.hbs 4 - --- 5 - 6 - <section> 7 - <WithBadge section="index" /> 8 - 9 - <div> 10 - <h1 className="special">Run JavaScript Everywhere</h1> 11 - 12 - Node.js® is a free, open-source, cross-platform JavaScript runtime 13 - environment that lets developers create servers, web apps, 14 - command line tools and scripts. 15 - 16 - </div> 17 - 18 - <div> 19 - <WithNodeRelease status={['Active LTS', 'Maintenance LTS']}> 20 - {({ release }) => ( 21 - <> 22 - <DownloadButton release={release}>Download Node.js (LTS)</DownloadButton> 23 - <small> 24 - Downloads Node.js <b>{release.versionWithPrefix}</b> 25 - <sup title="Downloads a Node.js installer for your current platform">1</sup> with long-term support. 26 - Node.js can also be installed via <a href="/download/package-manager">package managers</a>. 27 - </small> 28 - </> 29 - )} 30 - </WithNodeRelease> 31 - <WithNodeRelease status="Current"> 32 - {({ release }) => ( 33 - <small> 34 - Want new features sooner? 35 - Get <b>Node.js <DownloadLink release={release}>{release.versionWithPrefix}</DownloadLink></b> 36 - <sup title="Downloads a Node.js installer for your current platform">1</sup> instead. 37 - </small> 38 - )} 39 - </WithNodeRelease> 40 - </div> 41 - </section> 42 - 43 - <section> 44 - <div> 45 - ```js displayName="Create an HTTP Server" 46 - import { createServer } from 'node:http'; 47 - 48 - const server = createServer((req, res) => { 49 - res.writeHead(200, { 'Content-Type': 'text/plain' }); 50 - res.end('Hello World!\n'); 51 - }); 52 - 53 - // starts a simple http server locally on port 3000 54 - server.listen(3000, '127.0.0.1', () => { 55 - console.log('Listening on 127.0.0.1:3000'); 56 - }); 57 - ``` 58 - 59 - ```js displayName="Write Tests" 60 - import assert from 'node:assert'; 61 - import test from 'node:test'; 62 - 63 - test('that 1 is equal 1', () => { 64 - assert.strictEqual(1, 1); 65 - }); 66 - 67 - test('that throws as 1 is not equal 2', () => { 68 - // throws an exception because 1 != 2 69 - assert.strictEqual(1, 2); 70 - }); 71 - ``` 72 - 73 - ```js displayName="Read and Hash a File" 74 - import { createHash } from 'node:crypto'; 75 - import { readFile } from 'node:fs/promises'; 76 - 77 - const hasher = createHash('sha1'); 78 - const fileContent = await readFile('./package.json'); 79 - 80 - hasher.setEncoding('hex'); 81 - hasher.write(fileContent); 82 - hasher.end(); 83 - 84 - const fileHash = hasher.read(); 85 - ``` 86 - 87 - ```js displayName="Read Streams" 88 - import { createReadStream, createWriteStream } from 'node:fs'; 89 - 90 - const res = await fetch('https://nodejs.org/dist/index.json'); 91 - const json = await res.json(); // yields a json object 92 - 93 - const readableStream = createReadStream('./package.json'); 94 - const writableStream = createWriteStream('./package2.json'); 95 - 96 - readableStream.setEncoding('utf8'); 97 - 98 - readableStream.on('data', chunk => writableStream.write(chunk)); 99 - ``` 100 - 101 - ```js displayName="Work with Threads" 102 - import { Worker, isMainThread, 103 - workerData, parentPort } from 'node:worker_threads'; 104 - 105 - if (isMainThread) { 106 - const data = 'some data'; 107 - const worker = new Worker(import.meta.filename, { workerData: data }); 108 - worker.on('message', msg => console.log('Reply from Thread:', msg)); 109 - } else { 110 - const source = workerData; 111 - parentPort.postMessage(btoa(source.toUpperCase())); 112 - } 113 - ``` 114 - 115 - </div> 116 - Learn more what Node.js is able to offer with our [Learning materials](/learn). 117 - </section>
styles/new/base.css styles/base.css
styles/new/effects.css styles/effects.css
styles/new/index.css styles/index.css
styles/new/markdown.css styles/markdown.css
-121
styles/old/base.css
··· 1 - html { 2 - background-color: $white; 3 - box-sizing: border-box; 4 - color: $node-gray; 5 - font-size: 20px; 6 - font-weight: 400; 7 - line-height: 1.5; 8 - margin: 0; 9 - } 10 - 11 - header, 12 - #main, 13 - footer { 14 - display: flex; 15 - } 16 - 17 - h1, 18 - h2, 19 - h3, 20 - h4, 21 - h5 { 22 - font-weight: 700; 23 - } 24 - 25 - h2 { 26 - font-size: 1.3em; 27 - } 28 - 29 - a, 30 - a:link, 31 - a:active { 32 - border-radius: 5px; 33 - color: $node-green; 34 - text-decoration: none; 35 - } 36 - 37 - a:hover { 38 - background-color: $node-green; 39 - color: $white; 40 - 41 - code { 42 - background-color: transparent; 43 - color: $white; 44 - } 45 - } 46 - 47 - a.imagelink { 48 - display: inline-block; 49 - 50 - &:hover { 51 - background-color: transparent; 52 - } 53 - } 54 - 55 - strong, 56 - b { 57 - font-weight: 600; 58 - } 59 - 60 - p { 61 - a { 62 - @mixin padded-link 2px; 63 - } 64 - } 65 - 66 - img { 67 - border: none; 68 - display: block; 69 - height: auto; 70 - max-width: 100%; 71 - } 72 - 73 - code { 74 - border-radius: 3px; 75 - font-family: Consolas, Monaco, 'Andale Mono', monospace; 76 - font-size: 14px; 77 - padding: 0.2em 0.4em; 78 - } 79 - 80 - pre, 81 - code { 82 - background-color: #2e3440ff; 83 - border-radius: 3px; 84 - color: $white; 85 - } 86 - 87 - pre { 88 - padding: 0.75em 1.2em; 89 - 90 - code { 91 - display: grid; 92 - overflow-x: auto; 93 - padding: 1em; 94 - } 95 - } 96 - 97 - blockquote { 98 - margin: 0; 99 - padding: 0 1em; 100 - position: relative; 101 - 102 - &::before { 103 - background-color: rgb(0 0 0 / 14%); 104 - content: ''; 105 - display: block; 106 - height: 100%; 107 - left: 0; 108 - position: absolute; 109 - top: 0; 110 - width: 6px; 111 - } 112 - } 113 - 114 - iframe { 115 - border: none; 116 - } 117 - 118 - [data-theme='light'] .dark-mode-only, 119 - [data-theme='dark'] .light-mode-only { 120 - display: none; 121 - }
-140
styles/old/index.css
··· 1 - @charset "utf-8"; 2 - 3 - @import 'tailwindcss/utilities'; 4 - 5 - @import 'variables'; 6 - @import 'base'; 7 - @import 'utils'; 8 - @import 'layout/sticky-footer'; 9 - @import 'layout/grid'; 10 - @import 'layout/main'; 11 - @import 'layout/lists'; 12 - @import 'layout/dark-theme'; 13 - @import 'page-modules/jsfoundation'; 14 - @import 'page-modules/header'; 15 - @import 'page-modules/footer'; 16 - @import 'page-modules/home'; 17 - @import 'page-modules/blog-index'; 18 - @import 'page-modules/blog-post'; 19 - @import 'page-modules/download'; 20 - @import 'page-modules/scrollToTop'; 21 - @import 'page-modules/anchorLinks'; 22 - @import 'page-modules/prev-next-navigation'; 23 - 24 - article a { 25 - word-break: break-word; 26 - } 27 - 28 - .intro { 29 - font-size: 38px; 30 - line-height: 1.2; 31 - margin-top: 140px; 32 - 33 - h1 { 34 - font-size: inherit; 35 - margin-bottom: 15px; 36 - 37 - + p { 38 - margin-top: 0; 39 - } 40 - } 41 - 42 - span { 43 - color: $light-gray; 44 - display: block; 45 - } 46 - } 47 - 48 - #main { 49 - .has-side-nav { 50 - nav { 51 - margin-top: 1.5em; 52 - min-width: 200px; 53 - max-width: 250px; 54 - 55 - ul { 56 - list-style-type: none; 57 - margin: 0; 58 - padding: 0; 59 - } 60 - 61 - li { 62 - padding: 0.1em 0.5em; 63 - } 64 - 65 - a { 66 - display: block; 67 - line-height: 1; 68 - margin-left: -10px; 69 - margin-right: -10px; 70 - padding: 5px 10px; 71 - 72 - &.active, 73 - &.active:hover { 74 - background-color: $active-green; 75 - color: $white; 76 - } 77 - } 78 - } 79 - 80 - article { 81 - margin: 0 20px; 82 - overflow: hidden; 83 - flex: 1 1; 84 - } 85 - } 86 - } 87 - 88 - .edit-link { 89 - float: right; 90 - font-size: 0.9em; 91 - margin: 0.5em 0; 92 - } 93 - 94 - .color-lightgray { 95 - color: $light-gray; 96 - } 97 - 98 - a:hover .color-lightgray { 99 - color: $white; 100 - } 101 - 102 - .no-padding { 103 - padding: 0; 104 - } 105 - 106 - .highlight-box { 107 - background-color: $light-gray3; 108 - border-radius: 2px; 109 - margin-top: 1em; 110 - padding: 5px 15px; 111 - 112 - *:first-child { 113 - margin-top: 0.5rem; 114 - } 115 - } 116 - 117 - @media screen and (max-width: 1002px) { 118 - #main { 119 - article { 120 - ul:not(.no-padding) { 121 - margin: 0 20px; 122 - } 123 - } 124 - } 125 - } 126 - 127 - @media screen and (max-width: 480px) { 128 - #main { 129 - .has-side-nav { 130 - nav { 131 - max-width: 100%; 132 - } 133 - 134 - article { 135 - margin: 0; 136 - width: 100%; 137 - } 138 - } 139 - } 140 - }
-151
styles/old/layout/dark-theme.css
··· 1 - html[data-theme='dark'] { 2 - background-color: $dark-black; 3 - color: $white; 4 - 5 - .theme-switcher { 6 - img.light-image { 7 - display: none; 8 - } 9 - 10 - img.dark-image { 11 - display: block; 12 - } 13 - } 14 - 15 - .blogpost-meta { 16 - color: $white; 17 - } 18 - 19 - #main { 20 - p, 21 - h1, 22 - h2, 23 - h3 { 24 - color: $white; 25 - } 26 - 27 - a { 28 - color: $dark-green2; 29 - 30 - &:hover { 31 - color: $white; 32 - } 33 - 34 - &.active, 35 - &.active:hover { 36 - background-color: $active-green; 37 - color: $white; 38 - } 39 - } 40 - } 41 - 42 - header, 43 - .theme-switcher img, 44 - .lang-picker-toggler img { 45 - background-color: $dark-black2; 46 - } 47 - 48 - header { 49 - li { 50 - &::after { 51 - border-top-color: $dark-black2 !important; 52 - } 53 - } 54 - 55 - .lang-picker { 56 - background-color: $dark-black2; 57 - } 58 - } 59 - 60 - article { 61 - p { 62 - color: $light-gray3 !important; 63 - } 64 - 65 - a { 66 - color: $dark-green2; 67 - 68 - &:hover { 69 - background-color: $dark-green2; 70 - color: $white; 71 - } 72 - } 73 - 74 - li { 75 - color: $light-gray3; 76 - } 77 - 78 - table { 79 - background-color: $dark-black3; 80 - 81 - th { 82 - color: $white-alpha-b3; 83 - } 84 - 85 - td { 86 - color: $white; 87 - } 88 - 89 - tr:only-child, 90 - tr:nth-child(even) { 91 - background-color: $dark-black2 !important; 92 - } 93 - 94 - tr:nth-child(odd) { 95 - background-color: $black; 96 - } 97 - } 98 - 99 - .highlight-box { 100 - background-color: $dark-code-background; 101 - color: $light-gray3; 102 - } 103 - } 104 - 105 - footer { 106 - @media (max-width: 481px) { 107 - margin-top: 0 !important; 108 - } 109 - 110 - background-color: $dark-black2; 111 - 112 - .openjsfoundation-footer { 113 - background-color: $dark-black2; 114 - } 115 - } 116 - 117 - .home-version-banner { 118 - background-color: #1f2f2b; 119 - } 120 - 121 - .download-hero { 122 - a { 123 - background-color: $dark-green; 124 - color: #0aa007; 125 - 126 - &:hover { 127 - background-color: #438542; 128 - } 129 - } 130 - 131 - a.is-version * { 132 - color: $white; 133 - } 134 - } 135 - 136 - .download-matrix td { 137 - border-color: $light-gray; 138 - } 139 - 140 - .blog-index { 141 - .summary { 142 - color: $light-gray; 143 - font-size: 75%; 144 - margin-left: 1em; 145 - } 146 - } 147 - 148 - .header-background-fill { 149 - fill: $dark-black2; 150 - } 151 - }
-10
styles/old/layout/grid.css
··· 1 - .container { 2 - margin: 0 auto; 3 - max-width: $body-max-width; 4 - width: 100%; 5 - } 6 - 7 - .row { 8 - display: flex; 9 - flex-direction: row; 10 - }
-27
styles/old/layout/lists.css
··· 1 - .list-divider-pipe { 2 - margin: 0; 3 - padding: 0; 4 - 5 - li { 6 - display: inline-block; 7 - 8 - + li::before { 9 - color: $light-gray; 10 - content: '|'; 11 - padding: 0 0.3em 0 0.1em; 12 - } 13 - } 14 - } 15 - 16 - @media screen and (max-width: 480px) { 17 - nav { 18 - .list-divider-pipe { 19 - margin-bottom: 1rem; 20 - overflow: hidden; 21 - 22 - li + li::before { 23 - display: none; 24 - } 25 - } 26 - } 27 - }
-28
styles/old/layout/main.css
··· 1 - #main { 2 - .container { 3 - display: block; 4 - } 5 - 6 - .has-side-nav.container { 7 - flex-direction: row; 8 - display: flex; 9 - } 10 - } 11 - 12 - @media screen and (max-width: 1002px) { 13 - #main { 14 - .container { 15 - margin: 1em 20px; 16 - width: calc(100% - 40px); 17 - } 18 - } 19 - } 20 - 21 - @media screen and (max-width: 480px) { 22 - #main { 23 - .container, 24 - .has-side-nav.container { 25 - display: block; 26 - } 27 - } 28 - }
-25
styles/old/layout/sticky-footer.css
··· 1 - html, 2 - body { 3 - height: 100%; 4 - } 5 - 6 - body, 7 - #__next { 8 - display: flex; 9 - flex-direction: column; 10 - margin: 0; 11 - min-height: 100vh; 12 - } 13 - 14 - #main { 15 - flex: 1 0 auto; 16 - } 17 - 18 - header, 19 - footer { 20 - flex-shrink: 0; 21 - } 22 - 23 - footer { 24 - padding: 0 20px; 25 - }
-28
styles/old/page-modules/anchorLinks.css
··· 1 - .anchor { 2 - background: none; 3 - color: $light-gray2; 4 - padding: 0 0.25em; 5 - float: right; 6 - 7 - &:link, 8 - &:active, 9 - &:hover { 10 - background: inherit; 11 - color: $light-gray2; 12 - } 13 - 14 - &:focus::before { 15 - content: '#'; 16 - } 17 - } 18 - 19 - h1, 20 - h2, 21 - h3, 22 - h4, 23 - h5, 24 - h6 { 25 - &:hover > .anchor::before { 26 - content: '#'; 27 - } 28 - }
-34
styles/old/page-modules/blog-index.css
··· 1 - .blog-index { 2 - list-style: none; 3 - padding: 0; 4 - 5 - time { 6 - color: $light-gray; 7 - margin-right: 1em; 8 - } 9 - 10 - .summary { 11 - font-size: 75%; 12 - margin-left: 1em; 13 - } 14 - } 15 - 16 - nav.pagination { 17 - a { 18 - @mixin padded-link 2px; 19 - } 20 - } 21 - 22 - @media screen and (max-width: 700px) { 23 - .blog-index, 24 - .dark .blog-index { 25 - .summary { 26 - margin-left: 0; 27 - 28 - p { 29 - overflow: hidden; 30 - text-overflow: ellipsis; 31 - } 32 - } 33 - } 34 - }
-12
styles/old/page-modules/blog-post.css
··· 1 - .blogpost-header { 2 - border-bottom: 1px solid $light-gray2; 3 - padding-bottom: 0.5rem; 4 - 5 - h1 { 6 - margin-bottom: 0; 7 - } 8 - } 9 - 10 - .blogpost-meta { 11 - font-size: 1rem; 12 - }
-312
styles/old/page-modules/download.css
··· 1 - .download-table-currentpage { 2 - background-color: $node-green; 3 - color: $white; 4 - } 5 - 6 - .download-header { 7 - h1 { 8 - float: left; 9 - margin-bottom: -1rem; 10 - width: 40%; 11 - } 12 - 13 - ul { 14 - float: right; 15 - margin-top: 2rem; 16 - text-align: right; 17 - width: 40%; 18 - } 19 - } 20 - 21 - .download-header::after { 22 - clear: both; 23 - content: ''; 24 - display: block; 25 - } 26 - 27 - .download-hero { 28 - margin-bottom: 1em; 29 - 30 - ul { 31 - display: flex; 32 - list-style: none; 33 - margin: 0; 34 - overflow: hidden; 35 - text-align: center; 36 - } 37 - 38 - li { 39 - display: flex; 40 - flex-basis: 200px; 41 - flex-grow: 1; 42 - } 43 - 44 - a { 45 - background: $light-green; 46 - border-radius: 0 !important; 47 - color: $active-green; 48 - display: block; 49 - padding-top: 1em; 50 - width: 100%; 51 - } 52 - 53 - .download-logo { 54 - display: block; 55 - fill: $node-green; 56 - margin: 0 auto; 57 - } 58 - 59 - p { 60 - margin: 1em 0 0; 61 - padding-bottom: 1em; 62 - } 63 - 64 - a:hover { 65 - background: $node-green; 66 - color: $white; 67 - 68 - .download-logo { 69 - fill: $white; 70 - } 71 - } 72 - 73 - a:active { 74 - background: $active-green; 75 - color: $white; 76 - } 77 - 78 - .download-version-toggle { 79 - border-top-left-radius: 5px; 80 - border-top-right-radius: 5px; 81 - display: flex; 82 - flex-wrap: nowrap; 83 - 84 - a { 85 - border-radius: 0; 86 - padding: 5px 2px; 87 - } 88 - 89 - a:hover, 90 - a:active, 91 - a.is-version { 92 - background: $node-green; 93 - color: $white; 94 - } 95 - 96 - a.is-version { 97 - background: $active-green; 98 - color: $light-green; 99 - } 100 - 101 - .title { 102 - font-size: 1.5em; 103 - line-height: 1; 104 - } 105 - 106 - .tag { 107 - font-size: 0.8em; 108 - } 109 - } 110 - 111 - .download-platform { 112 - border-bottom-left-radius: 5px; 113 - border-bottom-right-radius: 5px; 114 - border-top: 2px solid $node-green; 115 - } 116 - } 117 - 118 - .download-matrix { 119 - margin-bottom: 1.5rem; 120 - 121 - th { 122 - text-align: left; 123 - width: 33%; 124 - } 125 - 126 - td { 127 - border: 1px solid $light-gray2; 128 - 129 - a, 130 - span { 131 - background: none; 132 - display: block; 133 - font-size: 0.8em; 134 - height: 100%; 135 - text-align: center; 136 - width: 100%; 137 - } 138 - 139 - a:hover, 140 - a:active { 141 - background: $node-green; 142 - color: $white; 143 - } 144 - } 145 - } 146 - 147 - h5.download-table-previous-releases-header { 148 - margin-bottom: 5px; 149 - } 150 - 151 - .download-table { 152 - border: 1px solid $light-gray2; 153 - border-spacing: 0; 154 - font-size: small; 155 - text-align: center; 156 - 157 - td { 158 - padding: 5px; 159 - } 160 - 161 - > thead { 162 - font-weight: 600; 163 - 164 - th:last-child { 165 - text-align: left; 166 - padding-left: 1.5rem; 167 - } 168 - } 169 - 170 - > tbody { 171 - td { 172 - border-top: 1px solid $light-gray2; 173 - } 174 - 175 - tr:nth-child(odd) { 176 - background-color: $light-gray3; 177 - } 178 - 179 - tr:nth-child(even) { 180 - background-color: $white; 181 - } 182 - } 183 - } 184 - 185 - td.download-table-last { 186 - text-align: right; 187 - 188 - > a { 189 - padding: 0 10px; 190 - } 191 - } 192 - 193 - @media (max-width: 700px) { 194 - .download-hero { 195 - ul { 196 - display: block; 197 - text-align: left; 198 - } 199 - 200 - li { 201 - display: block; 202 - text-align: center; 203 - } 204 - 205 - .download-version-toggle { 206 - display: flex; 207 - padding-right: 4px; 208 - 209 - li { 210 - display: inline-block; 211 - flex-basis: 160px; 212 - } 213 - 214 - .tag { 215 - font-size: 0.6em; 216 - } 217 - } 218 - } 219 - 220 - .download-matrix { 221 - display: block; 222 - 223 - th { 224 - display: block; 225 - width: 100%; 226 - } 227 - 228 - tr { 229 - display: block; 230 - margin-bottom: 1em; 231 - } 232 - 233 - td { 234 - border: none; 235 - display: block; 236 - 237 - a { 238 - text-align: left; 239 - } 240 - } 241 - } 242 - 243 - .download-table { 244 - border: none; 245 - 246 - > thead { 247 - display: none; 248 - } 249 - 250 - tr { 251 - display: block; 252 - margin-bottom: 10px; 253 - } 254 - 255 - td { 256 - display: block; 257 - text-align: right; 258 - } 259 - 260 - td:last-child { 261 - border-bottom: 0; 262 - } 263 - 264 - td::before { 265 - content: attr(data-label); 266 - float: left; 267 - font-weight: 600; 268 - } 269 - 270 - > thead > tr > th, 271 - > tbody > tr > th, 272 - > tfoot > tr > th, 273 - > thead > tr > td, 274 - > tbody > tr > td, 275 - > tfoot > tr > td, 276 - > tbody td { 277 - border: none; 278 - } 279 - } 280 - 281 - .download-table > tbody td { 282 - border: none; 283 - } 284 - 285 - td.download-table-last { 286 - text-align: center; 287 - } 288 - } 289 - 290 - @media screen and (max-width: 700px) { 291 - .download-matrix { 292 - display: revert; 293 - } 294 - 295 - .download-matrix ~ section ul { 296 - padding: 0 20px; 297 - } 298 - } 299 - 300 - @media (max-width: 320px) { 301 - .download-hero { 302 - .download-version-toggle { 303 - li { 304 - font-size: 1em; 305 - } 306 - 307 - .tag { 308 - font-size: 0.4em; 309 - } 310 - } 311 - } 312 - }
-20
styles/old/page-modules/footer.css
··· 1 - footer { 2 - background-color: $node-gray; 3 - margin-top: 2em; 4 - padding: 0; 5 - 6 - a, 7 - a:link, 8 - a:active { 9 - color: rgb(173 216 230); 10 - } 11 - 12 - a:hover { 13 - background-color: transparent; 14 - text-decoration: underline; 15 - } 16 - 17 - &.no-margin-top { 18 - margin-top: 0; 19 - } 20 - }
-227
styles/old/page-modules/header.css
··· 1 - header, 2 - .theme-switcher img, 3 - .lang-picker-toggler img { 4 - background-color: $node-gray; 5 - } 6 - 7 - header { 8 - position: relative; 9 - text-align: center; 10 - 11 - > .container { 12 - overflow: visible; 13 - } 14 - 15 - li { 16 - position: relative; 17 - } 18 - 19 - nav { 20 - cursor: default; 21 - 22 - a, 23 - a:link, 24 - a:active { 25 - color: $light-gray2 !important; 26 - font-size: 14px; 27 - padding: 0 8px; 28 - text-transform: uppercase; 29 - } 30 - 31 - a:hover { 32 - background-color: transparent; 33 - text-decoration: underline; 34 - } 35 - } 36 - 37 - .header-background-fill { 38 - fill: $node-gray; 39 - } 40 - 41 - .switchers { 42 - align-items: center; 43 - bottom: 0; 44 - display: flex; 45 - position: absolute; 46 - right: 0; 47 - top: 0; 48 - } 49 - 50 - .theme-switcher { 51 - border: none; 52 - cursor: pointer; 53 - margin: 0 8px 0 0; 54 - padding: 0; 55 - 56 - img.light-image { 57 - display: block; 58 - } 59 - 60 - img.dark-image { 61 - display: none; 62 - } 63 - } 64 - 65 - .lang-picker-toggler { 66 - border: none; 67 - color: $light-gray2; 68 - cursor: pointer; 69 - margin: 0 8px 0 0; 70 - padding: 0; 71 - } 72 - 73 - .lang-picker { 74 - background: $node-gray; 75 - list-style-type: none; 76 - margin: 0; 77 - max-height: 400px; 78 - overflow: auto; 79 - padding: 0; 80 - position: absolute; 81 - right: 0; 82 - top: 100%; 83 - z-index: 1; 84 - 85 - a { 86 - color: $light-gray2; 87 - } 88 - 89 - li { 90 - padding-bottom: 0; 91 - 92 - a { 93 - background-color: transparent; 94 - border: none; 95 - color: $light-gray2 !important; 96 - cursor: pointer; 97 - display: inline-block; 98 - font-family: inherit; 99 - font-size: 14px; 100 - line-height: 1.5; 101 - margin: 0 auto; 102 - padding: 0.5em 1em; 103 - text-transform: uppercase; 104 - 105 - &:focus, 106 - &:hover { 107 - background-color: $node-green; 108 - text-decoration: underline; 109 - } 110 - } 111 - } 112 - } 113 - 114 - .logo { 115 - align-items: center; 116 - bottom: 0; 117 - display: flex; 118 - justify-content: space-evenly; 119 - left: 0; 120 - margin: 0 10px 8px; 121 - position: absolute; 122 - top: 0; 123 - 124 - img { 125 - margin-bottom: -4px; 126 - } 127 - 128 - &:hover { 129 - background-color: transparent; 130 - text-decoration: underline; 131 - } 132 - } 133 - } 134 - 135 - @media screen and (min-width: 481px) { 136 - header { 137 - ul { 138 - min-height: 42px; 139 - 140 - li { 141 - margin-top: 4px; 142 - 143 - $border-width: 14px; 144 - 145 - &:has(a.active)::after { 146 - border: solid transparent; 147 - border-top-color: $node-gray; 148 - border-width: $border-width; 149 - content: ' '; 150 - height: 0; 151 - left: 50%; 152 - margin-left: calc(-$border-width * 0.5); 153 - pointer-events: none; 154 - position: absolute; 155 - top: 100%; 156 - width: 0; 157 - } 158 - 159 - &:has(a.active):first-child::after { 160 - margin-left: -$border-width; 161 - } 162 - } 163 - } 164 - 165 - a, 166 - a:link, 167 - a:active { 168 - padding: 0 8px; 169 - } 170 - } 171 - } 172 - 173 - @media screen and (max-width: 1000px) and (min-width: 743px), 174 - screen and (max-width: 881px) { 175 - header { 176 - .switchers { 177 - justify-content: center; 178 - margin: 10px 0 16px; 179 - position: unset; 180 - } 181 - 182 - .lang-picker { 183 - li { 184 - float: left; 185 - margin: 0; 186 - padding: 0; 187 - width: 50%; 188 - } 189 - } 190 - 191 - .logo { 192 - justify-content: center; 193 - margin: 10px 0 16px; 194 - position: unset; 195 - } 196 - } 197 - } 198 - 199 - @media screen and (max-width: 480px) { 200 - header { 201 - .switchers { 202 - justify-content: space-evenly; 203 - } 204 - 205 - li { 206 - float: left; 207 - margin: 0; 208 - padding: 0; 209 - width: 50%; 210 - } 211 - 212 - nav { 213 - margin: 0 20px; 214 - } 215 - 216 - a, 217 - a:link, 218 - a:active { 219 - padding: 0; 220 - } 221 - 222 - .lang-picker-toggler { 223 - padding: 0; 224 - position: relative; 225 - } 226 - } 227 - }
-209
styles/old/page-modules/home.css
··· 1 - .home-version { 2 - color: $gray; 3 - font-size: 16px; 4 - padding-top: 10px; 5 - } 6 - 7 - .home-version-banner { 8 - background-color: $light-green; 9 - border-radius: 2px; 10 - color: $node-gray; 11 - font-size: 130%; 12 - margin-top: 1em; 13 - padding: 5px 15px; 14 - 15 - a { 16 - color: $active-green; 17 - 18 - &:hover { 19 - color: $white; 20 - } 21 - } 22 - } 23 - 24 - .home-secondary-links { 25 - color: $home-secondary-links-color; 26 - font-size: 0.9rem; 27 - 28 - a { 29 - color: $home-secondary-links-color; 30 - 31 - &:hover { 32 - background-color: transparent; 33 - border-bottom: 1px solid $home-secondary-links-color; 34 - border-radius: 0; 35 - } 36 - } 37 - } 38 - 39 - #home-intro { 40 - margin: 0 auto; 41 - max-width: calc($body-max-width * 0.75); 42 - padding: 30px 0; 43 - text-align: center; 44 - 45 - h2 { 46 - margin-bottom: 0; 47 - } 48 - } 49 - 50 - .home-banner { 51 - opacity: 1; 52 - transition: opacity 0.2s ease-in-out; 53 - 54 - &:hover { 55 - opacity: 0.85; 56 - } 57 - 58 - > img { 59 - border-radius: 10px; 60 - } 61 - } 62 - 63 - .home-downloadblock { 64 - display: inline-block; 65 - margin: 0 8px; 66 - } 67 - 68 - .home-downloadbutton { 69 - background-color: $active-green; 70 - border-radius: 10px; 71 - color: $white !important; 72 - display: block; 73 - font-size: 30px; 74 - font-weight: 400; 75 - margin: 10px 4px; 76 - padding: 0.2em 0.6em; 77 - transition: background-color 0.2s ease-in-out; 78 - 79 - &:hover { 80 - background-color: $node-green; 81 - } 82 - 83 - small { 84 - display: block; 85 - font-size: 1rem; 86 - } 87 - } 88 - 89 - /** 90 - * BLM CTA button styles. 91 - */ 92 - 93 - .home-blacklivesmatterblock { 94 - display: block; 95 - font-size: 16px; 96 - height: 4rem; 97 - position: relative; 98 - } 99 - 100 - .home-blacklivesmatterbutton { 101 - color: $white !important; 102 - display: block; 103 - font-size: 130%; 104 - font-weight: 400; 105 - left: 50%; 106 - max-width: 100%; 107 - padding: 0.5em 20%; 108 - position: absolute; 109 - top: 50%; 110 - transform: translateX(-50%) translateY(-50%); 111 - transition: padding 0.2s ease-in-out; 112 - 113 - &:active, 114 - &:focus, 115 - &:hover { 116 - padding: calc(0.5em * 1.2) calc(20% * 1.2); 117 - } 118 - 119 - small { 120 - display: block; 121 - font-size: 1rem; 122 - } 123 - } 124 - 125 - /** 126 - * Accessible button role styles (copypasta) integrated into site color scheme. 127 - * @author W3C 128 - * @see https://www.w3.org/TR/wai-aria-practices/examples/button/button.html 129 - */ 130 - 131 - [role='button'] { 132 - background-color: hsl(0deg 0% 31%); 133 - background-image: linear-gradient( 134 - to bottom, 135 - hsl(0deg 0% 33%), 136 - hsl(0deg 0% 27%) 137 - ); 138 - border: 1px solid hsl(0deg 0% 39%); 139 - border-radius: 5px; 140 - box-shadow: 0 1px 2px hsl(0deg 0% 45%); 141 - color: #fff; 142 - text-shadow: 0 -1px 1px hsl(0deg 0% 15%); 143 - } 144 - 145 - [role='button']:hover { 146 - background-color: hsl(0deg 0% 21%); 147 - background-image: linear-gradient( 148 - to bottom, 149 - hsl(0deg 0% 23%), 150 - hsl(0deg 0% 17%) 151 - ); 152 - border-color: hsl(0deg 0% 19%); 153 - cursor: pointer; 154 - } 155 - 156 - [role='button']:focus { 157 - outline: none; 158 - } 159 - 160 - [role='button']:focus::before { 161 - border: 3px solid hsl(0deg 0% 39%); 162 - 163 - /* button border radius + outline width + offset */ 164 - border-radius: calc(5px + 3px + 3px); 165 - content: ''; 166 - inset: calc(-1px - 3px - 3px) calc(-1px - 3px - 3px) calc(-1px - 3px - 3px) 167 - calc(-1px - 3px - 3px); 168 - position: absolute; 169 - 170 - /* button border width - outline width - offset */ 171 - z-index: -1; 172 - } 173 - 174 - [role='button']:active { 175 - background-color: hsl(0deg 0% 11%); 176 - background-image: linear-gradient( 177 - to bottom, 178 - hsl(0deg 0% 33%), 179 - hsl(0deg 0% 27%) 180 - ); 181 - border-color: hsl(0deg 0% 29%); 182 - box-shadow: inset 0 3px 5px 1px hsl(0deg 0% 10%); 183 - } 184 - 185 - [role='button'][aria-pressed] { 186 - background-color: hsl(0deg 0% 31%); 187 - background-image: linear-gradient( 188 - to bottom, 189 - hsl(0deg 0% 33%), 190 - hsl(0deg 0% 27%) 191 - ); 192 - border-color: hsl(0deg 0% 29%); 193 - box-shadow: 0 1px 2px hsl(0deg 0% 35%); 194 - text-shadow: 0 -1px 1px hsl(0deg 0% 5%); 195 - } 196 - 197 - [role='button'][aria-pressed]:hover { 198 - background-color: hsl(0deg 0% 31%); 199 - background-image: linear-gradient( 200 - to bottom, 201 - hsl(0deg 0% 13%), 202 - hsl(0deg 0% 7%) 203 - ); 204 - border-color: hsl(0deg 0% 9%); 205 - } 206 - 207 - [role='button'][aria-pressed]:focus::before { 208 - border-color: hsl(0deg 0% 29%); 209 - }
-88
styles/old/page-modules/jsfoundation.css
··· 1 - .openjsfoundation-footer { 2 - background: $node-gray; 3 - color: $white; 4 - direction: ltr; 5 - float: left; 6 - font-size: small; 7 - padding: 1em 20px; 8 - text-align: center; 9 - 10 - p + p { 11 - font-size: 15px; 12 - } 13 - } 14 - 15 - .openjsfoundation-footer-edit { 16 - display: inline; 17 - font-size: 15px; 18 - } 19 - 20 - .openjsfoundation-footer-links { 21 - display: inline; 22 - } 23 - 24 - .issue-link-container { 25 - align-items: center; 26 - display: flex; 27 - } 28 - 29 - .issue-link { 30 - margin-left: auto; 31 - min-width: 330px; 32 - text-align: left; 33 - } 34 - 35 - .help { 36 - color: $white; 37 - font-size: 14px; 38 - margin-top: 3em; 39 - width: 40%; 40 - } 41 - 42 - @media (min-width: 280px) { 43 - .help { 44 - margin-left: 10%; 45 - } 46 - } 47 - 48 - @media (min-width: 320px) { 49 - .help { 50 - margin-left: 58%; 51 - } 52 - } 53 - 54 - @media (min-width: 500px) { 55 - .help { 56 - margin-left: 65%; 57 - } 58 - } 59 - 60 - @media (min-width: 768px) { 61 - .help { 62 - margin-left: 70%; 63 - } 64 - } 65 - 66 - @media screen and (max-width: 700px) { 67 - .issue-link-container { 68 - flex-wrap: wrap; 69 - } 70 - 71 - .issue-link { 72 - margin: 1em 0 0; 73 - min-width: 0; 74 - text-align: start; 75 - } 76 - } 77 - 78 - @media screen and (max-width: 480px) { 79 - .openjsfoundation-footer { 80 - padding: 3em 20px; 81 - width: auto; 82 - } 83 - 84 - .help { 85 - margin-left: auto; 86 - width: auto; 87 - } 88 - }
-11
styles/old/page-modules/prev-next-navigation.css
··· 1 - .btn-navigation { 2 - padding: 0.1em 0.5em; 3 - 4 - &.btn-prev { 5 - float: left; 6 - } 7 - 8 - &.btn-next { 9 - float: right; 10 - } 11 - }
-7
styles/old/page-modules/scrollToTop.css
··· 1 - html { 2 - scroll-behavior: smooth; 3 - 4 - @media (prefers-reduced-motion: reduce) { 5 - scroll-behavior: auto; 6 - } 7 - }
-39
styles/old/utils.css
··· 1 - .bg-white { 2 - background-color: $white !important; 3 - } 4 - 5 - .bg-node-gray { 6 - background-color: $node-gray !important; 7 - } 8 - 9 - .table-no-border-no-padding { 10 - border-spacing: 0; 11 - 12 - td { 13 - padding: 0; 14 - } 15 - } 16 - 17 - .sr-only { 18 - border: none; 19 - clip: rect(0, 0, 0, 0); 20 - height: 1px; 21 - overflow: hidden; 22 - padding: 0; 23 - position: absolute; 24 - white-space: nowrap; 25 - width: 1px; 26 - } 27 - 28 - .hidden { 29 - display: none; 30 - } 31 - 32 - .full-width { 33 - width: 100%; 34 - } 35 - 36 - small, 37 - .small { 38 - font-size: 0.7rem; 39 - }
-34
styles/old/variables.css
··· 1 - $body-max-width: 980px; 2 - 3 - $black: #000; 4 - $white: #fff; 5 - $white-alpha-b3: #ffffffb3; 6 - $node-green: #43853d; 7 - $light-green: #eaf5e9; 8 - $active-green: #026e00; 9 - 10 - $light-gray3: #f0f0f0; 11 - $light-gray2: #ccc; 12 - $light-gray: #999; 13 - $gray: #666; 14 - $node-gray: #333; 15 - $home-secondary-links-color: #51744e; 16 - $black-alpha-80: #00000080; 17 - $black-alpha-12: #00000012; 18 - $black-alpha-0f: #0000000f; 19 - 20 - $dark-black: #090c15; 21 - $dark-black2: #233056; 22 - $dark-black3: #23305671; 23 - $dark-gray: #242424; 24 - $dark-green: #2c372a; 25 - $dark-green2: #84ba64; 26 - $dark-green3: #64de64; 27 - $dark-code-background: #2c3437; 28 - 29 - @define-mixin padded-link $padding { 30 - margin-left: calc($padding * -1); 31 - margin-right: calc($padding * -1); 32 - padding-left: $padding; 33 - padding-right: $padding; 34 - }
-4
turbo.json
··· 16 16 "NEXT_PUBLIC_ORAMA_API_KEY", 17 17 "NEXT_PUBLIC_ORAMA_ENDPOINT", 18 18 "NEXT_PUBLIC_VERCEL_REVALIDATE_TIME", 19 - "NEXT_PUBLIC_ENABLE_REDESIGN", 20 19 "NEXT_PUBLIC_DATA_URL" 21 20 ] 22 21 }, ··· 40 39 "NEXT_PUBLIC_ORAMA_API_KEY", 41 40 "NEXT_PUBLIC_ORAMA_ENDPOINT", 42 41 "NEXT_PUBLIC_VERCEL_REVALIDATE_TIME", 43 - "NEXT_PUBLIC_ENABLE_REDESIGN", 44 42 "NEXT_PUBLIC_DATA_URL" 45 43 ] 46 44 }, ··· 58 56 "NEXT_PUBLIC_ORAMA_API_KEY", 59 57 "NEXT_PUBLIC_ORAMA_ENDPOINT", 60 58 "NEXT_PUBLIC_VERCEL_REVALIDATE_TIME", 61 - "NEXT_PUBLIC_ENABLE_REDESIGN", 62 59 "NEXT_PUBLIC_DATA_URL" 63 60 ] 64 61 }, ··· 82 79 "NEXT_PUBLIC_ORAMA_API_KEY", 83 80 "NEXT_PUBLIC_ORAMA_ENDPOINT", 84 81 "NEXT_PUBLIC_VERCEL_REVALIDATE_TIME", 85 - "NEXT_PUBLIC_ENABLE_REDESIGN", 86 82 "NEXT_PUBLIC_DATA_URL" 87 83 ] 88 84 },
-2
types/features.ts
··· 13 13 export interface WebsiteBanner extends WithRange { 14 14 text: string; 15 15 link?: string; 16 - /** @deprecated the html field is unsupported on the website redesign */ 17 - html?: string; 18 16 type?: 'default' | 'warning' | 'error'; 19 17 } 20 18
+2 -2
types/frontmatter.ts
··· 1 - import type { LegacyLayouts } from './layouts'; 1 + import type { Layouts } from './layouts'; 2 2 3 3 // @TODO: Extra data from Frontmatter should not be a thing in the future 4 4 // eslint-disable-next-line @typescript-eslint/no-explicit-any 5 5 export interface LegacyFrontMatter extends Record<string, any> { 6 - layout?: LegacyLayouts; 6 + layout?: Layouts; 7 7 title?: string; 8 8 labels?: Record<string, string>; 9 9 }
-12
types/layouts.ts
··· 1 - // @TODO: These are the Website Redesign Layouts 2 1 export type Layouts = 3 2 | 'about.hbs' 4 3 | 'home.hbs' ··· 8 7 | 'blog-post.hbs' 9 8 | 'search.hbs' 10 9 | 'download.hbs'; 11 - 12 - // @TODO: These are legacy layouts that are going to be replaced with the `nodejs/nodejs.dev` Layouts in the future 13 - export type LegacyLayouts = 14 - | 'about.hbs' 15 - | 'learn.hbs' 16 - | 'blog-category.hbs' 17 - | 'blog-post.hbs' 18 - | 'index.hbs' 19 - | 'docs.hbs' 20 - | 'download.hbs' 21 - | 'page.hbs';
+1 -1
types/release.ts
··· 3 3 import type { NodeRelease } from '@/types/releases'; 4 4 import type { UserOS } from '@/types/userOS'; 5 5 6 - export type PackageManager = 'NVM' | 'BREW' | 'DOCKER'; 6 + export type PackageManager = 'NVM' | 'BREW' | 'DOCKER' | 'CHOCO'; 7 7 8 8 export interface ReleaseState { 9 9 os: UserOS;
+4 -6
util/downloadUtils.ts
··· 1 - import { ENABLE_WEBSITE_REDESIGN } from '@/next.constants.mjs'; 2 1 import type { PackageManager } from '@/types/release'; 3 2 import type { UserOS } from '@/types/userOS'; 4 3 ··· 33 32 { 34 33 label: 'Brew', 35 34 value: 'BREW' as PackageManager, 35 + }, 36 + { 37 + label: 'Chocolatey', 38 + value: 'CHOCO' as PackageManager, 36 39 }, 37 40 { 38 41 label: 'Docker', ··· 114 117 // Returns the page, category and subCategoy information to be used in the page 115 118 // from the pathname information on the download pages. 116 119 export const getDownloadCategory = (pathname: string) => { 117 - /** @deprecated once the website redesign happens remove this code block */ 118 - if (ENABLE_WEBSITE_REDESIGN) { 119 - pathname = pathname.replace('/new-design', ''); 120 - } 121 - 122 120 const segments = pathname.split('/').filter(Boolean); 123 121 const [, c] = segments; 124 122
+70 -60
util/getNodeDownloadSnippet.ts
··· 1 1 import dedent from 'dedent'; 2 2 3 + import type { NodeRelease } from '@/types'; 4 + import type { PackageManager } from '@/types/release'; 3 5 import type { UserOS } from '@/types/userOS'; 4 6 5 - export const getNodeDownloadSnippet = (major: number, os: UserOS) => { 7 + export const getNodeDownloadSnippet = (release: NodeRelease, os: UserOS) => { 8 + const snippets: Record<PackageManager, string> = { 9 + NVM: '', 10 + BREW: '', 11 + DOCKER: '', 12 + CHOCO: '', 13 + }; 14 + 6 15 if (os === 'LINUX' || os === 'MAC') { 7 - const platformSnippets = { 8 - NVM: dedent` 9 - # Installs NVM (Node Version Manager) 10 - curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash 16 + snippets.NVM = dedent` 17 + # installs NVM (Node Version Manager) 18 + curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash 11 19 12 - # Installs Node.js 13 - nvm install v${major} 20 + # download and install Node.js 21 + nvm install ${release.major} 14 22 15 - # Checks that Node is installed 16 - node -v 23 + # verifies the right Node.js version is in the environment 24 + node -v # should print \`${release.versionWithPrefix}\` 17 25 18 - # Checks your NPM version 19 - npm -v`, 20 - BREW: dedent` 21 - # Installs Brew (macOS/Linux Package Manager) 22 - curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash 26 + # verifies the right NPM version is in the environment 27 + npm -v # should print \`${release.npm}\``; 23 28 24 - # Installs Node.js 25 - brew install node@${major} 29 + snippets.BREW = dedent` 30 + # download and installs Homebrew (macOS/Linux Package Manager) 31 + curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash 26 32 27 - # Checks that Node is installed 28 - node -v 33 + # download and install Node.js 34 + brew install node@${release.major} 29 35 30 - # Checks your NPM version 31 - npm -v`, 32 - DOCKER: '', 33 - }; 36 + # verifies the right Node.js version is in the environment 37 + node -v # should print \`${release.versionWithPrefix}\` 34 38 35 - if (os === 'MAC') { 36 - platformSnippets.DOCKER = dedent` 37 - # Installs Brew (macOS Package Manager) 38 - curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash 39 + # verifies the right NPM version is in the environment 40 + npm -v # should print \`${release.npm}\``; 41 + } 39 42 40 - # Installs Docker Desktop 41 - brew install docker --cask 43 + if (os === 'MAC') { 44 + snippets.DOCKER = dedent` 45 + # installs Homebrew (macOS/Linux Package Manager) 46 + curl -o- https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh | bash 42 47 43 - # Pull Node.js Docker Image 44 - docker pull node:${major}-${major >= 4 ? 'alpine' : 'slim'} 45 - `; 46 - } 48 + # installs Docker Desktop 49 + brew install docker --cask 47 50 48 - return platformSnippets; 51 + # pulls the Node.js Docker image 52 + docker pull node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} 53 + 54 + # verifies the right Node.js version is in the environment 55 + docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} node -v # should print \`${release.versionWithPrefix}\` 56 + 57 + # verifies the right NPM version is in the environment 58 + docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} npm -v # should print \`${release.npm}\``; 49 59 } 50 60 51 61 if (os === 'WIN') { 52 - return { 53 - NVM: dedent` 54 - # Installs Chocolatey (Windows Package Manager) 55 - Set-ExecutionPolicy Bypass -Scope Process -Force; 56 - [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; 57 - iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')); 62 + snippets.CHOCO = dedent` 63 + # installs Chocolatey (Windows Package Manager) 64 + Set-ExecutionPolicy Bypass -Scope Process -Force; 65 + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; 66 + iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')); 67 + 68 + # download and install Node.js 69 + choco install nodejs --version="${release.version}" 58 70 59 - # Installs NVM (Node Version Manager) 60 - choco install nvm 71 + # verifies the right Node.js version is in the environment 72 + node -v # should print \`${release.versionWithPrefix}\` 61 73 62 - # Installs Node.js 63 - nvm install v${major} 74 + # verifies the right NPM version is in the environment 75 + npm -v # should print \`${release.npm}\``; 76 + 77 + snippets.DOCKER = dedent` 78 + # installs Chocolatey (Windows Package Manager) 79 + Set-ExecutionPolicy Bypass -Scope Process -Force; 80 + [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; 81 + iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1')); 64 82 65 - # Checks that Node is installed 66 - node -v 83 + # installs Docker Desktop 84 + choco install docker-desktop 67 85 68 - # Checks your NPM version 69 - npm -v`, 70 - DOCKER: dedent` 71 - # Installs Chocolatey (Windows Package Manager) 72 - Set-ExecutionPolicy Bypass -Scope Process -Force; 73 - [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor 3072; 74 - iex ((New-Object System.Net.WebClient).DownloadString('https://community.chocolatey.org/install.ps1')); 86 + # pulls the Node.js Docker image 87 + docker pull node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} 75 88 76 - # Installs Docker Desktop 77 - choco install docker-desktop 89 + # verifies the right Node.js version is in the environment 90 + docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} node -v # should print \`${release.versionWithPrefix}\` 78 91 79 - # Pull Node.js Docker Image 80 - docker pull node:${major}-${major >= 4 ? 'alpine' : 'slim'} 81 - `, 82 - BREW: '', 83 - }; 92 + # verifies the right NPM version is in the environment 93 + docker run node:${release.major}-${release.major >= 4 ? 'alpine' : 'slim'} npm -v # should print \`${release.npm}\``; 84 94 } 85 95 86 - return { NVM: '', BREW: '', DOCKER: '' }; 96 + return snippets; 87 97 };