fix download cv, ym

This commit is contained in:
Sergey Krylov 2025-03-26 11:14:22 +03:00
parent 002b9de9e5
commit 35782233ef
8 changed files with 58 additions and 40 deletions

View File

@ -1,5 +1,3 @@
version: '3.8'
services: services:
nextjs: nextjs:
image: node:18-alpine image: node:18-alpine

16
package-lock.json generated
View File

@ -16,6 +16,7 @@
"next": "15.2.4", "next": "15.2.4",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-yandex-metrika": "^2.6.0",
"tailwind-merge": "^3.0.2", "tailwind-merge": "^3.0.2",
"tw-animate-css": "^1.2.4" "tw-animate-css": "^1.2.4"
}, },
@ -4374,7 +4375,6 @@
"version": "4.0.0", "version": "4.0.0",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/js-yaml": { "node_modules/js-yaml": {
@ -4750,7 +4750,6 @@
"version": "1.4.0", "version": "1.4.0",
"resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz",
"integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"js-tokens": "^3.0.0 || ^4.0.0" "js-tokens": "^3.0.0 || ^4.0.0"
@ -4943,7 +4942,6 @@
"version": "4.1.1", "version": "4.1.1",
"resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz",
"integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==",
"dev": true,
"license": "MIT", "license": "MIT",
"engines": { "engines": {
"node": ">=0.10.0" "node": ">=0.10.0"
@ -5242,7 +5240,6 @@
"version": "15.8.1", "version": "15.8.1",
"resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz",
"integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==",
"dev": true,
"license": "MIT", "license": "MIT",
"dependencies": { "dependencies": {
"loose-envify": "^1.4.0", "loose-envify": "^1.4.0",
@ -5306,7 +5303,6 @@
"version": "16.13.1", "version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"dev": true,
"license": "MIT" "license": "MIT"
}, },
"node_modules/react-remove-scroll": { "node_modules/react-remove-scroll": {
@ -5378,6 +5374,16 @@
} }
} }
}, },
"node_modules/react-yandex-metrika": {
"version": "2.6.0",
"resolved": "https://registry.npmjs.org/react-yandex-metrika/-/react-yandex-metrika-2.6.0.tgz",
"integrity": "sha512-8K4wExsNZtY3DTxh1G8a+zWH9Pg8fw23MJcoJ4I/562qrHRnh7L5nteq3lnNL58dnNQbuuHIRoGgMjIo+r1GjA==",
"license": "MIT",
"peerDependencies": {
"prop-types": "*",
"react": "*"
}
},
"node_modules/reflect.getprototypeof": { "node_modules/reflect.getprototypeof": {
"version": "1.0.10", "version": "1.0.10",
"resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz", "resolved": "https://registry.npmjs.org/reflect.getprototypeof/-/reflect.getprototypeof-1.0.10.tgz",

View File

@ -17,6 +17,7 @@
"next": "15.2.4", "next": "15.2.4",
"react": "^19.0.0", "react": "^19.0.0",
"react-dom": "^19.0.0", "react-dom": "^19.0.0",
"react-yandex-metrika": "^2.6.0",
"tailwind-merge": "^3.0.2", "tailwind-merge": "^3.0.2",
"tw-animate-css": "^1.2.4" "tw-animate-css": "^1.2.4"
}, },

View File

@ -1,4 +1,4 @@
import { Metrika } from '@/components/metrika'; import YandexMetrikaContainer, { Metrika } from '@/components/metrika';
import type { Metadata } from "next"; import type { Metadata } from "next";
import { Geist, Geist_Mono } from "next/font/google"; import { Geist, Geist_Mono } from "next/font/google";
import "./globals.css"; import "./globals.css";
@ -26,6 +26,8 @@ export const metadata: Metadata = {
} }
}; };
const analyticsEnabled = (process.env.NODE_ENV === "production");
export default function RootLayout({ export default function RootLayout({
children, children,
}: Readonly<{ }: Readonly<{
@ -38,10 +40,8 @@ export default function RootLayout({
> >
{children} {children}
<Suspense> <YandexMetrikaContainer enabled={analyticsEnabled} />
<Metrika /> </body>
</Suspense>
</body>
</html> </html>
); );
} }

View File

@ -61,14 +61,14 @@ export default function Home() {
<DropdownMenuContent> <DropdownMenuContent>
<DropdownMenuLabel>Download CV</DropdownMenuLabel> <DropdownMenuLabel>Download CV</DropdownMenuLabel>
<DropdownMenuSeparator/> <DropdownMenuSeparator/>
<Link href="/docs/Крылов%20Сергей,%20Frontend%20Developer.pdf"> <Link href="/docs/Крылов_Сергей-Frontend_Developer.pdf">
<DropdownMenuItem> <DropdownMenuItem>
<Image src="/icons/pdf.svg" alt="pdf icon" height={16} width={16} className="grayscale"/> <Image src="/icons/pdf.svg" alt="pdf icon" height={16} width={16} className="grayscale"/>
PDF PDF
</DropdownMenuItem> </DropdownMenuItem>
</Link> </Link>
<Link href="/docs/Крылов%20Сергей,%20Frontend%20Developer.docx"> <Link href="/docs/Крылов_Сергей-Frontend_Developer.docx">
<DropdownMenuItem> <DropdownMenuItem>
<Image src="/icons/docx.svg" alt="docx icon" height={16} width={16} className="grayscale"/> <Image src="/icons/docx.svg" alt="docx icon" height={16} width={16} className="grayscale"/>
DOCX DOCX

View File

@ -1,34 +1,47 @@
"use client"; "use client";
import { useEffect } from "react"; import Router from "next/router";
import { usePathname, useSearchParams } from "next/navigation"; import React, { useCallback, useEffect } from "react";
import Script from "next/script"; import ym, { YMInitializer } from "react-yandex-metrika";
export function Metrika() { type Props = {
const pathName = usePathname(); enabled: boolean;
const searchParams = useSearchParams(); };
const YM_COUNTER_ID = 100593564;
const YandexMetrikaContainer: React.FC<Props> = ({ enabled }) => {
const hit = useCallback(
(url: string) => {
if (enabled) {
ym("hit", url);
} else {
console.log(`%c[YandexMetrika](HIT)`, `color: orange`, url);
}
},
[enabled],
);
useEffect(() => { useEffect(() => {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment hit(window.location.pathname + window.location.search);
// @ts-expect-error Router.events.on("routeChangeComplete", (url: string) => hit(url));
window.ym(100593564, "hit", window.location.href); }, [hit]);
}, [pathName, searchParams]);
if (!enabled) return null;
return ( return (
<Script id="yandex-metrika"> <YMInitializer
{` accounts={[YM_COUNTER_ID]}
(function(m,e,t,r,i,k,a){m[i]=m[i]||function(){(m[i].a=m[i].a||[]).push(arguments)}; options={{
m[i].l=1*new Date(); defer: true,
for (var j = 0; j < document.scripts.length; j++) {if (document.scripts[j].src === r) { return; }} webvisor: true,
k=e.createElement(t),a=e.getElementsByTagName(t)[0],k.async=1,k.src=r,a.parentNode.insertBefore(k,a)}) clickmap: true,
(window, document, "script", "https://mc.yandex.ru/metrika/tag.js", "ym"); trackLinks: true,
accurateTrackBounce: true,
ym(100593564, "init", { }}
clickmap:true, version="2"
trackLinks:true, />
accurateTrackBounce:true
})
`}
</Script>
); );
} };
export default YandexMetrikaContainer;