Ymetrika update (#245)
* update claude with message about components * yandex metrika to ts * rm env * add .env example * use account from env * add tests
This commit is contained in:
1 parent
013578b518
commit
8c57976663
7 files changed
+60
-11
No files matched your search
+1
-1
@@ -1,2 +1,2 @@
|
||||
APP_CARD_DEFAULT_IMAGE=https://art.shlisselburg.org/static/img/main.jpg
|
||||
|
||||
NEXT_PUBLIC_YMETRIKA_ACCOUNT=XXX
|
||||
@@ -21,3 +21,4 @@ dist
|
||||
.vercel
|
||||
.next
|
||||
tsconfig.tsbuildinfo
|
||||
.env
|
||||
@@ -26,6 +26,18 @@ Feature branches are named `issue-XXX` where `XXX` is the related GitHub issue n
|
||||
|
||||
ESLint 9 flat config (`eslint.config.js`) using `FlatCompat` from `@eslint/eslintrc` to bridge `eslint-config-next` (which doesn't support native flat config in Next.js 15.x). Extends `next/core-web-vitals`. Enforces: no semicolons, double quotes, 4-space indentation, always-multiline trailing commas, `eol-last`.
|
||||
|
||||
**React components:** Use regular function declarations (not arrow functions) and `type` for props. Do not use `React.FC`.
|
||||
|
||||
```tsx
|
||||
export type MyComponentProps = {
|
||||
value: string
|
||||
}
|
||||
|
||||
export function MyComponent({ value }: MyComponentProps) {
|
||||
return <div>{value}</div>
|
||||
}
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
**Pages Router with SSG/ISR:** All pages use `getStaticProps`/`getStaticPaths` with 30-second revalidation. The catch-all route `pages/[...slug].tsx` handles all dynamic content pages.
|
||||
|
||||
+4
-2
@@ -7,7 +7,7 @@ import "src/style/kazimir/video.css"
|
||||
import App from "next/app"
|
||||
import Head from "next/head"
|
||||
import Script from "next/script"
|
||||
import { YMetrika } from "src/components/YMetrika"
|
||||
import { YMetrika } from "@/components/YMetrika"
|
||||
import { ThemeColor } from "@/ui/ThemeColor"
|
||||
|
||||
export default class MyApp extends App {
|
||||
@@ -41,7 +41,9 @@ export default class MyApp extends App {
|
||||
href="/feed.xml"
|
||||
/>
|
||||
|
||||
<YMetrika account={24027460} />
|
||||
{process.env.NEXT_PUBLIC_YMETRIKA_ACCOUNT && (
|
||||
<YMetrika account={Number(process.env.NEXT_PUBLIC_YMETRIKA_ACCOUNT)} />
|
||||
)}
|
||||
|
||||
<ThemeColor
|
||||
color="white"
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
import { describe, it, expect } from "vitest"
|
||||
import { script } from "./YMetrika"
|
||||
|
||||
describe("YMetrika script", () => {
|
||||
it("should embed account id into metrika counter variable", () => {
|
||||
const result = script(99999)
|
||||
expect(result).toContain("w.yaCounter99999")
|
||||
})
|
||||
|
||||
it("should embed account id into metrika config", () => {
|
||||
const result = script(99999)
|
||||
expect(result).toContain("id:99999")
|
||||
})
|
||||
|
||||
it("should include metrika watch.js script url", () => {
|
||||
const result = script(99999)
|
||||
expect(result).toContain("https://mc.yandex.ru/metrika/watch.js")
|
||||
})
|
||||
|
||||
it("should use yandex_metrika_callbacks", () => {
|
||||
const result = script(99999)
|
||||
expect(result).toContain("yandex_metrika_callbacks")
|
||||
})
|
||||
|
||||
it("should produce different output for different accounts", () => {
|
||||
const a = script(11111)
|
||||
const b = script(22222)
|
||||
expect(a).toContain("yaCounter11111")
|
||||
expect(b).toContain("yaCounter22222")
|
||||
expect(a).not.toContain("yaCounter22222")
|
||||
})
|
||||
})
|
||||
@@ -1,6 +1,8 @@
|
||||
import React from "react"
|
||||
export type YMetrikaProps = {
|
||||
account: number
|
||||
}
|
||||
|
||||
function script(account) {
|
||||
export function script(account: number) {
|
||||
return `
|
||||
(function (d, w, c) {
|
||||
(w[c] = w[c] || []).push(function() {
|
||||
@@ -14,14 +16,14 @@ function script(account) {
|
||||
});
|
||||
} catch(e) { }
|
||||
});
|
||||
|
||||
|
||||
var n = d.getElementsByTagName("script")[0],
|
||||
s = d.createElement("script"),
|
||||
f = function () { n.parentNode.insertBefore(s, n); };
|
||||
s.type = "text/javascript";
|
||||
s.async = true;
|
||||
s.src = "https://mc.yandex.ru/metrika/watch.js";
|
||||
|
||||
|
||||
if (w.opera == "[object Opera]") {
|
||||
d.addEventListener("DOMContentLoaded", f, false);
|
||||
} else { f(); }
|
||||
@@ -29,6 +31,6 @@ function script(account) {
|
||||
`
|
||||
}
|
||||
|
||||
export const YMetrika = (props) => (
|
||||
<script dangerouslySetInnerHTML={{ __html: script(props.account) }} />
|
||||
)
|
||||
export function YMetrika({ account }: YMetrikaProps) {
|
||||
return <script dangerouslySetInnerHTML={{ __html: script(account) }} />
|
||||
}
|
||||
+1
-1
@@ -9,6 +9,6 @@ export default defineConfig({
|
||||
},
|
||||
},
|
||||
test: {
|
||||
include: ["src/**/*.test.ts"],
|
||||
include: ["src/**/*.test.{ts,tsx}"],
|
||||
},
|
||||
})
|
||||
Reference in new issue
Block a user