The Node.js® Website
1'use client';
2
3import { useTranslations } from 'next-intl';
4import { useContext, useEffect, useState } from 'react';
5import type { FC } from 'react';
6
7import CodeBox from '@/components/Common/CodeBox';
8import { ReleaseContext } from '@/providers/releaseProvider';
9import { getShiki, highlightToHtml } from '@/util/getHighlighter';
10import { getNodeDownloadSnippet } from '@/util/getNodeDownloadSnippet';
11
12// We cannot do top-level awaits on utilities or code that is imported by client-only components
13// hence we only declare a Promise and let it be fulfilled by the first call to the function
14const memoizedShiki = getShiki();
15
16const ReleaseCodeBox: FC = () => {
17 const { platform, os, release } = useContext(ReleaseContext);
18
19 const [code, setCode] = useState('');
20 const t = useTranslations();
21
22 useEffect(() => {
23 const updatedCode = getNodeDownloadSnippet(release, os)[platform];
24 // Docker and NVM support downloading tags/versions by their full release number
25 // but usually we should recommend users to download "major" versions
26 // since our Downlooad Buttons get the latest minor of a major, it does make sense
27 // to request installation of a major via a package manager
28 memoizedShiki
29 .then(shiki => highlightToHtml(shiki)(updatedCode, 'bash'))
30 .then(setCode);
31 // Only react when the specific release number changed
32 // eslint-disable-next-line react-hooks/exhaustive-deps
33 }, [release.versionWithPrefix, os, platform]);
34
35 return (
36 <div className="mb-2 mt-6 flex min-h-80 flex-col gap-2">
37 {code && (
38 <CodeBox language="Bash">
39 <code dangerouslySetInnerHTML={{ __html: code }} />
40 </CodeBox>
41 )}
42
43 <span className="text-center text-xs text-neutral-800 dark:text-neutral-200">
44 {t('layouts.download.codeBox.communityWarning')}
45 </span>
46 </div>
47 );
48};
49
50export default ReleaseCodeBox;