Skip to content

feat: Introduce Downloads Archive page #7794

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 57 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
3937420
feat: simplified download page
canerakdas May 20, 2025
fa51777
chore: resolve conflict
canerakdas May 20, 2025
3e9cbeb
chore: fix type errors
canerakdas May 20, 2025
8abad4e
chore: remove unused css file
canerakdas May 20, 2025
924c640
refactor: release check and version without minor
canerakdas May 20, 2025
9c375d5
refactor: better localization
canerakdas May 25, 2025
e586292
refactor: separate layout, markdown and sidebar logic
canerakdas May 25, 2025
644882f
refactor: simple download utils
canerakdas May 25, 2025
4a0fd1c
refactor: getNodeDownloadUrl args destructuring
canerakdas May 25, 2025
426f4ed
refactor: localize and improve sidebar getter
canerakdas May 25, 2025
1f6e3db
refactor: better naming, docs and alias import
canerakdas May 25, 2025
dfd47a0
chore: sidebargroup naming
canerakdas May 25, 2025
fd09988
fix: active simplified sidebar and more docs
canerakdas May 25, 2025
0f1ae0a
feat: simple download meta bar added
canerakdas May 28, 2025
9c96639
chore: details styles moved into the site app
canerakdas May 29, 2025
bb5c03c
chore: details styles moved into the site app
canerakdas May 29, 2025
7f9c14b
fix: win x64, mac arm64 semver compat
canerakdas May 29, 2025
107b9f7
refactor: self review
canerakdas May 29, 2025
b07ba56
docs: downloads table
canerakdas May 29, 2025
5b30781
docs: fileoverview removed
canerakdas May 31, 2025
17cc8a0
fix: layout import
canerakdas May 31, 2025
a92ad35
Update apps/site/next.mdx.use.mjs
canerakdas May 31, 2025
c7264ea
refactor: layout changes
canerakdas Jun 2, 2025
199c3e6
refactor: renamed to download archive
canerakdas Jun 2, 2025
8a43b85
refactor: enhance buildReleaseArtifacts
canerakdas Jun 3, 2025
968517f
chore: resolve conflict
canerakdas Jun 3, 2025
1e6e0f4
docs: updating according to layout/naming
canerakdas Jun 4, 2025
52b6cdc
Update apps/site/util/downloadUtils/archive.tsx
canerakdas Jun 4, 2025
2759b68
chore: review updates
canerakdas Jun 4, 2025
7186a9b
Merge branch 'feat/simplified-download' of https://github.com/canerak…
canerakdas Jun 4, 2025
2eaa893
fix: scroll and archive artifacts
canerakdas Jun 4, 2025
31400af
refactor: minor versions table
canerakdas Jun 5, 2025
e516c0b
chore: lint
canerakdas Jun 5, 2025
1417339
feat: release alert box
canerakdas Jun 5, 2025
7358d16
chore: previous releases links
canerakdas Jun 5, 2025
b832299
refactor: version navigation and content
canerakdas Jun 5, 2025
0fa1f1d
fix: separator, modal border color
canerakdas Jun 6, 2025
2b17e6b
feat: DownloadReleasesTable download archive redirects
canerakdas Jun 6, 2025
f533ebc
refactor: markdown content editing and Node.js logo added
canerakdas Jun 6, 2025
1c8abdd
feat: home page button redirects
canerakdas Jun 6, 2025
d241894
refactor: minor text and styling updates
canerakdas Jun 8, 2025
edaf4e1
Merge branch 'main' into feat/simplified-download
canerakdas Jun 8, 2025
6099b93
chore: resolve conflict
canerakdas Jul 11, 2025
2eb64c7
chore: resolve conflict
canerakdas Jul 12, 2025
91b436d
chore: unused component removed
canerakdas Jul 12, 2025
2ebb662
chore: resolve conflict
canerakdas Aug 2, 2025
aad1be0
chore: revert downloadbutton
canerakdas Aug 2, 2025
ec457eb
fix: missing exports
canerakdas Aug 2, 2025
e0f68e8
refactor: stateless select used instead of the HTML details element
canerakdas Aug 2, 2025
c794154
feat: group download archive navigation by release status
canerakdas Aug 2, 2025
2d7da01
fix: placeholder for non latest versions
canerakdas Aug 2, 2025
7a92ef5
feat: fixed header for scrollable table, minor version identifier and…
canerakdas Aug 2, 2025
339ad9a
fix: dark mode border color
canerakdas Aug 2, 2025
dfcd073
fix: duplicated alertbox message
canerakdas Aug 3, 2025
76aaabb
refactor: unnecessary use client usage
canerakdas Aug 10, 2025
dfcef36
fix: throw error when version not exist
canerakdas Aug 10, 2025
cfea26f
Merge branch 'main' into feat/simplified-download
canerakdas Aug 10, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/site/components/Downloads/DownloadButton/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,13 @@ import styles from './index.module.css';
type DownloadButtonProps = { release: NodeRelease };

const DownloadButton: FC<PropsWithChildren<DownloadButtonProps>> = ({
release: { versionWithPrefix },
release: { versionWithPrefix: version },
children,
}) => {
const { os, bitness, architecture } = useClientContext();

const platform = getUserPlatform(architecture, bitness);
const downloadLink = getNodeDownloadUrl(versionWithPrefix, os, platform);
const downloadLink = getNodeDownloadUrl({ version, os, platform });

return (
<>
Expand Down
12 changes: 6 additions & 6 deletions apps/site/components/Downloads/DownloadLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@ const DownloadLink: FC<PropsWithChildren<DownloadLinkProps>> = ({

const platform = getUserPlatform(architecture, bitness);

const downloadLink = getNodeDownloadUrl(
versionWithPrefix,
os,
platform,
kind
);
const downloadLink = getNodeDownloadUrl({
version: versionWithPrefix,
os: os,
platform: platform,
kind: kind,
});

return <LinkWithArrow href={downloadLink}>{children}</LinkWithArrow>;
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import type { FC } from 'react';

import FormattedTime from '#site/components/Common/FormattedTime';
import DetailsButton from '#site/components/Downloads/DownloadReleasesTable/DetailsButton';
import Link from '#site/components/Link';
import provideReleaseData from '#site/next-data/providers/releaseData';

const BADGE_KIND_MAP = {
Expand Down Expand Up @@ -33,7 +34,11 @@ const DownloadReleasesTable: FC = () => {
<tbody>
{releaseData.map(release => (
<tr key={release.major}>
<td data-label="Version">v{release.major}</td>
<td data-label="Version">
<Link href={`/download/${release.versionWithPrefix}`}>
v{release.major}
</Link>
</td>
<td data-label="LTS">{release.codename || '-'}</td>
<td data-label="Date">
<FormattedTime date={release.currentStart} />
Expand Down
47 changes: 47 additions & 0 deletions apps/site/components/Downloads/DownloadsTable/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import { useTranslations } from 'next-intl';
import type { FC } from 'react';

import Link from '#site/components/Link';
import { OperatingSystemLabel } from '#site/util/download';
import type { NodeDownloadArtifact } from '#site/util/download/archive';

type DownloadsTableProps = {
source: Array<NodeDownloadArtifact>;
};

const DownloadsTable: FC<DownloadsTableProps> = ({ source }) => {
const t = useTranslations();

return (
<table>
<thead>
<tr>
<th>{t('components.downloadsTable.fileName')}</th>
<th className="md:w-28">
{t('components.downloadsTable.operatingSystem')}
</th>
<th className="md:w-28">
{t('components.downloadsTable.architecture')}
</th>
</tr>
</thead>
<tbody>
{source.map(release => (
<tr key={`${release.file}-${release.architecture}`}>
<td data-label={t('components.downloadsTable.fileName')}>
<Link href={release.url}>{release.file}</Link>
</td>
<td data-label={t('components.downloadsTable.operatingSystem')}>
{OperatingSystemLabel[release.os]}
</td>
<td data-label={t('components.downloadsTable.architecture')}>
{release.architecture}
</td>
</tr>
))}
</tbody>
</table>
);
};

export default DownloadsTable;
Original file line number Diff line number Diff line change
@@ -1,8 +1,51 @@
@reference "../../../styles/index.css";

.links {
.additionalLinks {
@apply flex
h-4
items-center
gap-2;
}

.items {
@apply flex
h-9
gap-2;
}

.scrollable {
@apply scrollbar-thin
flex
max-h-[29rem]
overflow-y-auto;

table {
@apply xs:border-t-0
border-t;
}

th {
@apply xs:border-t
border-neutral-200
dark:border-neutral-800;
}
}

.information {
@apply md:w-96;
}

.links {
@apply md:w-44;
}

.stickyHeader {
@apply top-0
z-10
border-t
bg-white
text-left
font-semibold
sm:sticky
dark:bg-neutral-950;
}
123 changes: 79 additions & 44 deletions apps/site/components/Downloads/MinorReleasesTable/index.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
'use client';

import { CodeBracketSquareIcon } from '@heroicons/react/24/outline';
import Separator from '@node-core/ui-components/Common/Separator';
import NpmIcon from '@node-core/ui-components/Icons/PackageManager/Npm';
import { useTranslations } from 'next-intl';
import type { FC } from 'react';

import { ReleaseOverviewItem } from '#site/components/Downloads/ReleaseOverview';
import Link from '#site/components/Link';
import LinkWithArrow from '#site/components/LinkWithArrow';
import { BASE_CHANGELOG_URL } from '#site/next.constants.mjs';
import type { MinorVersion } from '#site/types';
import { getNodeApiUrl } from '#site/util/url';
Expand All @@ -15,50 +17,83 @@ type MinorReleasesTableProps = {
releases: Array<MinorVersion>;
};

export const MinorReleasesTable: FC<MinorReleasesTableProps> = ({
releases,
}) => {
const t = useTranslations('components.minorReleasesTable');
const MinorReleasesTable: FC<MinorReleasesTableProps> = ({ releases }) => {
const t = useTranslations();

return (
<table>
<thead>
<tr>
<th>{t('version')}</th>
<th>{t('links')}</th>
</tr>
</thead>
<tbody>
{releases.map(release => (
<tr key={release.version}>
<td>v{release.version}</td>
<td>
<div className={styles.links}>
<Link
kind="neutral"
href={`https://nodejs.org/download/release/v${release.version}/`}
>
{t('actions.release')}
</Link>
<Separator orientation="vertical" />
<Link
kind="neutral"
href={`${BASE_CHANGELOG_URL}${release.version}`}
>
{t('actions.changelog')}
</Link>
<Separator orientation="vertical" />
<Link
kind="neutral"
href={getNodeApiUrl(`v${release.version}`)}
>
{t('actions.docs')}
</Link>
</div>
</td>
<div className={styles.scrollable}>
<table>
<thead className={styles.stickyHeader}>
<tr>
<th>{t('components.minorReleasesTable.version')}</th>
<th className={styles.information}>
{t('components.minorReleasesTable.information')}
</th>
<th className={styles.links}>
{t('components.minorReleasesTable.links')}
</th>
</tr>
))}
</tbody>
</table>
</thead>
<tbody>
{releases.map(release => (
<tr key={release.version}>
<td>
<Link kind="neutral" href={`/download/v${release.version}`}>
v{release.version}
</Link>
</td>
<td>
<div className={styles.items}>
{release.modules && (
<>
<ReleaseOverviewItem
Icon={CodeBracketSquareIcon}
title={`v${release.modules}`}
subtitle={t('components.releaseOverview.nApiVersion')}
/>
<Separator orientation="vertical" />
</>
)}
{release.npm && (
<>
<ReleaseOverviewItem
Icon={NpmIcon}
title={`v${release.npm}`}
subtitle={t('components.releaseOverview.npmVersion')}
/>
<Separator orientation="vertical" />
</>
)}
<ReleaseOverviewItem
Icon={CodeBracketSquareIcon}
title={`v${release.v8}`}
subtitle={t('components.releaseOverview.v8Version')}
/>
</div>
</td>
<td>
<div className={styles.additionalLinks}>
<Link
kind="neutral"
href={getNodeApiUrl(`v${release.version}`)}
>
{t('components.minorReleasesTable.actions.docs')}
</Link>
<Separator orientation="vertical" />
<LinkWithArrow
kind="neutral"
href={`${BASE_CHANGELOG_URL}${release.version}`}
>
{t('components.minorReleasesTable.actions.changelog')}
</LinkWithArrow>
</div>
</td>
</tr>
))}
</tbody>
</table>
</div>
);
};

export default MinorReleasesTable;
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,21 @@ const PrebuiltDownloadButtons: FC = () => {
const { release, os, platform } = useContext(ReleaseContext);

const installerUrl = platform
? getNodeDownloadUrl(release.versionWithPrefix, os, platform, 'installer')
? getNodeDownloadUrl({
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OOC, why is this function now taking an object?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some parameters in this function are optional for example, when generating a shasum or source link, providing only the version and kind is sufficient. Instead of calling

getNodeDownloadUrl(version, undefined, undefined, 'source')

it feels more readable to use a named parameter approach;

getNodeDownloadUrl({ version, kind: 'source' })

version: release.versionWithPrefix,
os: os,
platform: platform,
kind: 'installer',
})
: '';

const binaryUrl = platform
? getNodeDownloadUrl(release.versionWithPrefix, os, platform, 'binary')
? getNodeDownloadUrl({
version: release.versionWithPrefix,
os: os,
platform: platform,
kind: 'binary',
})
: '';

return (
Expand Down
27 changes: 3 additions & 24 deletions apps/site/components/Downloads/Release/ReleaseCodeBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { useContext, useMemo } from 'react';
import CodeBox from '#site/components/Common/CodeBox';
import Link from '#site/components/Link';
import LinkWithArrow from '#site/components/LinkWithArrow';
import WithReleaseAlertBox from '#site/components/withReleaseAlertBox';
import { createSval } from '#site/next.jsx.compiler.mjs';
import {
ReleaseContext,
Expand Down Expand Up @@ -107,37 +108,15 @@ const ReleaseCodeBox: FC = () => {
>
{t.rich('layouts.download.codeBox.noScriptDetected', {
link: text => (
<Link href="/about/previous-releases#looking-for-latest-release-of-a-version-branch">
<Link href="/download/archive">
<b>{text}</b>
</Link>
),
})}
</AlertBox>
</noscript>

{release.status === 'End-of-life' && (
<AlertBox
title={t('components.common.alertBox.warning')}
level="warning"
size="small"
>
{t.rich('layouts.download.codeBox.unsupportedVersionWarning', {
link: text => <Link href="/about/previous-releases/">{text}</Link>,
})}
</AlertBox>
)}

{release.isLts && (
<AlertBox
title={t('components.common.alertBox.info')}
level="info"
size="small"
>
{t.rich('layouts.download.codeBox.ltsVersionFeaturesNotice', {
link: text => <Link href="/download/current">{text}</Link>,
})}
</AlertBox>
)}
<WithReleaseAlertBox status={release.status} />

{!currentPlatform || currentPlatform.recommended || (
<AlertBox
Expand Down
8 changes: 5 additions & 3 deletions apps/site/components/Downloads/ReleaseModal/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,10 @@ import { Modal, Title, Content } from '@node-core/ui-components/Common/Modal';
import { useTranslations } from 'next-intl';
import type { FC } from 'react';

import { MinorReleasesTable } from '#site/components/Downloads/MinorReleasesTable';
import { ReleaseOverview } from '#site/components/Downloads/ReleaseOverview';
import MinorReleasesTable from '#site/components/Downloads/MinorReleasesTable';
import ReleaseOverview from '#site/components/Downloads/ReleaseOverview';
import Link from '#site/components/Link';
import WithReleaseAlertBox from '#site/components/withReleaseAlertBox';
import type { NodeRelease } from '#site/types';

type ReleaseModalProps = {
Expand All @@ -26,12 +27,13 @@ const ReleaseModal: FC<ReleaseModalProps> = ({
: 'components.releaseModal.titleWithoutCodename';

const modalHeading = t(modalHeadingKey, {
version: release.major,
version: `v${release.major}`,
codename: release.codename ?? '',
});

return (
<Modal open={isOpen} onOpenChange={closeModal}>
<WithReleaseAlertBox status={release.status} />
{release.status === 'End-of-life' && (
<div className="mb-4">
<AlertBox
Expand Down
Loading
Loading