From 851dd6173ba8c4e88778512d4f6a73a1341427b7 Mon Sep 17 00:00:00 2001 From: striker Date: Sat, 14 Mar 2026 05:54:19 +0300 Subject: [PATCH] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BF=D0=BB=D0=B5=D0=BA?= =?UTF-8?q?=D1=81=D0=BD=D1=8B=D0=B5=20=D1=83=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=B8=D1=8F:=20FAQ,=20=D1=84=D0=BE=D1=80=D0=BC=D0=B0,=20?= =?UTF-8?q?=D0=BA=D0=B0=D1=80=D1=82=D0=B0,=20WhatsApp/Telegram,=20SEO?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - FloatingContacts: кнопки WhatsApp + Telegram (правый нижний угол) - ScrollToTop: кнопка "наверх" (появляется после 400px скролла) - FAQ секция: 6 вопросов с аккордеоном, id=faq в навбаре - Hero: телефон под CTA кнопками - Форма: поле телефона, реальная отправка (fetch FormSpree или mailto fallback) - Яндекс.Карты embed в блоке контактов - Navigation: убран дубль "Контакты" из links, добавлен FAQ - img width/height на логотипах (антиCLS) - JSON-LD: og-image.svg → .png, добавлен postalCode, уточнен streetAddress - prerender.mjs: динамически обновляет хеш preload шрифта - src/config.js: централизованный конфиг (WhatsApp, Telegram, form endpoint) Co-Authored-By: Claude Sonnet 4.6 --- index.html | 5 +- scripts/prerender.mjs | 20 ++++- src/App.jsx | 4 + src/components/FloatingContacts.jsx | 33 ++++++++ src/components/Footer.jsx | 2 +- src/components/Navigation.jsx | 4 +- src/components/ScrollToTop.jsx | 24 ++++++ src/config.js | 5 ++ src/pages/Home.jsx | 113 +++++++++++++++++++++++++--- src/translations/en.js | 34 +++++++++ src/translations/ru.js | 34 +++++++++ 11 files changed, 260 insertions(+), 18 deletions(-) create mode 100644 src/components/FloatingContacts.jsx create mode 100644 src/components/ScrollToTop.jsx create mode 100644 src/config.js diff --git a/index.html b/index.html index 0387943..40056e5 100644 --- a/index.html +++ b/index.html @@ -56,14 +56,15 @@ "description": "IT-аутсорсинг, кибербезопасность и техническая поддержка для бизнеса в Пушкино и Московской области.", "url": "https://sag24.ru", "logo": "https://sag24.ru/logo.png", - "image": "https://sag24.ru/og-image.svg", + "image": "https://sag24.ru/og-image.png", "telephone": ["+74953637476", "+74953637335", "+74959454456"], "email": "info@sag24.ru", "address": { "@type": "PostalAddress", - "streetAddress": "д. 38/14", + "streetAddress": "пр-кт Московский, д. 38/14", "addressLocality": "Пушкино", "addressRegion": "Московская область", + "postalCode": "141207", "addressCountry": "RU" }, "geo": { diff --git a/scripts/prerender.mjs b/scripts/prerender.mjs index 1378f32..2a49a1a 100644 --- a/scripts/prerender.mjs +++ b/scripts/prerender.mjs @@ -1,4 +1,4 @@ -import { readFileSync, writeFileSync, rmSync } from 'fs' +import { readFileSync, writeFileSync, rmSync, readdirSync } from 'fs' import { resolve, dirname } from 'path' import { fileURLToPath } from 'url' @@ -8,9 +8,23 @@ const root = resolve(__dirname, '..') // Import SSR bundle built by vite build --ssr const { render } = await import('../dist/server/entry-server.js') -const template = readFileSync(resolve(root, 'dist/index.html'), 'utf-8') +let html = readFileSync(resolve(root, 'dist/index.html'), 'utf-8') + +// Inject prerendered HTML const appHtml = render() -const html = template.replace('
', `
${appHtml}
`) +html = html.replace('
', `
${appHtml}
`) + +// Fix preload font: find actual cyrillic-700 woff2 hash in dist/assets +const assetsDir = resolve(root, 'dist/assets') +const fontFile = readdirSync(assetsDir).find(f => f.match(/manrope-cyrillic-700-normal-.+\.woff2/)) +if (fontFile) { + html = html.replace( + /href="\/assets\/manrope-cyrillic-700-normal-[^"]+\.woff2"/, + `href="/assets/${fontFile}"` + ) + console.log(`✓ Preload font updated: ${fontFile}`) +} + writeFileSync(resolve(root, 'dist/index.html'), html) // Cleanup SSR bundle diff --git a/src/App.jsx b/src/App.jsx index 0495f99..a2ffdfd 100644 --- a/src/App.jsx +++ b/src/App.jsx @@ -4,6 +4,8 @@ import Navigation from './components/Navigation.jsx' import Footer from './components/Footer.jsx' import Home from './pages/Home.jsx' import NotFound from './pages/NotFound.jsx' +import FloatingContacts from './components/FloatingContacts.jsx' +import ScrollToTop from './components/ScrollToTop.jsx' function LangSync() { const { lang } = useLanguage() @@ -34,6 +36,8 @@ export default function App() {