Astro calendar_today 23 апр. 2026 г. schedule 2 мин

Корпоративный сайт на Astro: Гайд для бизнеса 2026

Как создать профессиональный корпоративный сайт на Astro.js: структура страниц, Headless CMS для редакторов, мультиязычность, форма обратной связи и SEO.

person
Журналист
Автор
Корпоративный сайт на Astro — бизнес-сайт 2026

Корпоративный сайт — визитная карточка бизнеса. Его цели: создать доверие, предоставить информацию и привлечь клиентов. Astro идеально подходит: молниеносная загрузка, отличное SEO, простое управление контентом через Headless CMS.

Почему Astro для корпоративного сайта?

  • PageSpeed 100 — скорость влияет на конверсию и SEO
  • Безопасность — нет PHP, нет БД в боевом контуре
  • Стоимость — Cloudflare Pages бесплатно или ~$5/мес
  • Управление контентом — Headless CMS для нетехнических редакторов
  • SEO — структурированные данные, ситмап, канонические URL из коробки

Типовая структура корпоративного сайта

code
company-site/
├── src/
│   ├── content/
│   │   ├── pages/          # Статичные страницы (Услуги, О нас)
│   │   ├── news/           # Новости и пресс-релизы
│   │   ├── cases/          # Кейсы / Портфолио
│   │   └── team/           # Команда
│   ├── pages/
│   │   ├── index.astro     # Главная
│   │   ├── about.astro     # О компании
│   │   ├── services/
│   │   │   ├── index.astro # Все услуги
│   │   │   └── [slug].astro# Страница услуги
│   │   ├── cases/
│   │   │   ├── index.astro # Кейсы
│   │   │   └── [slug].astro# Детальный кейс
│   │   ├── news/
│   │   │   ├── index.astro # Новости
│   │   │   └── [slug].astro# Новость
│   │   ├── team.astro      # Команда
│   │   ├── contacts.astro  # Контакты + форма
│   │   └── careers.astro   # Вакансии
│   └── components/
│       ├── Header.astro
│       ├── Footer.astro
│       ├── Hero.astro
│       ├── ServiceCard.astro
│       ├── CaseCard.astro
│       ├── TeamMember.astro
│       └── ContactForm.tsx  # Preact-остров

Content Collections для всех разделов

code
// src/content.config.ts
import { defineCollection, z } from 'astro:content';
import { glob } from 'astro/loaders';

// Услуги
const services = defineCollection({
  loader: glob({ pattern: '**/*.mdx', base: './src/content/services' }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      shortDescription: z.string().max(200),
      icon: z.string(), // material-symbols имя иконки
      cover: image().optional(),
      featured: z.boolean().default(false),
      order: z.number().default(999),
    }),
});

// Кейсы
const cases = defineCollection({
  loader: glob({ pattern: '**/*.mdx', base: './src/content/cases' }),
  schema: ({ image }) =>
    z.object({
      title: z.string(),
      client: z.string(),
      industry: z.string(),
      result: z.string(), // Ключевой результат одной строкой
      tags: z.array(z.string()),
      cover: image(),
      date: z.coerce.date(),
      featured: z.boolean().default(false),
    }),
});

// Новости
const news = defineCollection({
  loader: glob({ pattern: '**/*.mdx', base: './src/content/news' }),
  schema: z.object({
    title: z.string(),
    description: z.string(),
    date: z.coerce.date(),
    category: z.enum(['Новость', 'Пресс-релиз', 'Событие']),
    draft: z.boolean().default(false),
  }),
});

// Команда
const team = defineCollection({
  loader: glob({ pattern: '**/*.mdx', base: './src/content/team' }),
  schema: ({ image }) =>
    z.object({
      name: z.string(),
      position: z.string(),
      photo: image(),
      linkedin: z.string().url().optional(),
      email: z.string().email().optional(),
      order: z.number().default(999),
    }),
});

export const collections = { services, cases, news, team };

Главная страница

code
---
// src/pages/index.astro
import { getCollection } from 'astro:content';
import BaseLayout from '../layouts/BaseLayout.astro';
import Hero from '../components/Hero.astro';
import ServiceCard from '../components/ServiceCard.astro';
import CaseCard from '../components/CaseCard.astro';
import ContactForm from '../components/ContactForm.tsx';

// Данные из Content Collections
const services = await getCollection('services', (s) => s.data.featured);
const cases = await getCollection('cases', (c) => c.data.featured);
const sortedServices = services.sort((a, b) => a.data.order - b.data.order);
---

<BaseLayout
  title="Название компании — Описание деятельности"
  description="Чем занимается компания, её ключевые преимущества"
>
  <!-- Hero: ценностное предложение -->
  <Hero
    headline="Разрабатываем цифровые продукты для бизнеса"
    subheadline="200+ проектов с 2015 года. От стартапа до enterprise"
    cta={{ label: 'Обсудить проект', href: '#contact' }}
  />

  <!-- Услуги -->
  <section id="services">
    <h2>Что мы делаем</h2>
    <div class="grid grid-cols-3">
      {
        sortedServices.map((s) => (
          <ServiceCard
            title={s.data.title}
            description={s.data.shortDescription}
            icon={s.data.icon}
            slug={s.id.replace('.mdx', '')}
          />
        ))
      }
    </div>
  </section>

  <!-- Кейсы -->
  <section id="cases">
    <h2>Наши проекты</h2>
    <div class="grid grid-cols-2">
      {cases.map((c) => <CaseCard case={c} />)}
    </div>
    <a href="/cases/">Все проекты →</a>
  </section>

  <!-- Форма контакта — Preact-остров -->
  <section id="contact">
    <h2>Обсудим ваш проект</h2>
    <ContactForm
      client:visible
      fields={['name', 'company', 'email', 'phone', 'message']}
      submitTo="/api/contact"
    />
  </section>
</BaseLayout>

Structured Data (JSON-LD) для компании

code
---
// src/layouts/BaseLayout.astro
const organizationSchema = {
  '@context': 'https://schema.org',
  '@type': 'Organization',
  name: 'Название компании',
  url: 'https://company.ru',
  logo: 'https://company.ru/logo.png',
  contactPoint: {
    '@type': 'ContactPoint',
    telephone: '+7-XXX-XXX-XX-XX',
    contactType: 'sales',
    availableLanguage: 'Russian',
  },
  address: {
    '@type': 'PostalAddress',
    addressLocality: 'Москва',
    addressCountry: 'RU',
  },
  sameAs: [
    'https://vk.com/company',
    'https://t.me/company',
    'https://linkedin.com/company/company',
  ],
};
---

<script type="application/ld+json" set:html={JSON.stringify(organizationSchema)} />

Headless CMS для редакторов

Для нетехнических редакторов контента подключите Keystatic или Decap CMS:

code
# Keystatic — Git-based, работает локально
npm install @keystatic/core @keystatic/astro

Редакторы получают удобный визуальный интерфейс, а контент хранится в Git — никаких баз данных в боевом контуре.

Подробнее — в статье Headless CMS для Astro.

Форма обратной связи с Telegram-уведомлениями

code
// src/pages/api/contact.ts
import type { APIRoute } from 'astro';

export const POST: APIRoute = async ({ request }) => {
  const data = await request.json();
  const { name, company, email, phone, message } = data;

  // Отправка в Telegram через Bot API
  const botToken = import.meta.env.TELEGRAM_BOT_TOKEN;
  const chatId = import.meta.env.TELEGRAM_CHAT_ID;

  const text = `
🔔 *Новая заявка с сайта*

👤 *Имя:* ${name}
🏢 *Компания:* ${company || 'Не указана'}
📧 *Email:* ${email}
📱 *Телефон:* ${phone || 'Не указан'}

💬 *Сообщение:*
${message}
  `.trim();

  await fetch(`https://api.telegram.org/bot${botToken}/sendMessage`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      chat_id: chatId,
      text,
      parse_mode: 'Markdown',
    }),
  });

  return new Response(JSON.stringify({ ok: true }));
};

Мультиязычность (i18n)

Для международных компаний — встроенный i18n Astro:

code
// astro.config.mjs
export default defineConfig({
  i18n: {
    defaultLocale: 'ru',
    locales: ['ru', 'en'],
    routing: {
      prefixDefaultLocale: false, // /ru/ убрать, /en/ оставить
    },
  },
});
code
src/pages/
├── index.astro          → https://company.ru/
├── en/
│   └── index.astro      → https://company.ru/en/

SEO для корпоративного сайта

Ключевые точки:

  1. ГлавнаяWebSite + Organization JSON-LD
  2. УслугиService JSON-LD с описанием и ценой
  3. КейсыArticle или CreativeWork JSON-LD
  4. КомандаPerson JSON-LD для каждого сотрудника
  5. КонтактыContactPage JSON-LD с адресом и телефоном

Деплой и обновление контента

Рабочий процесс:

  1. Редактор вносит изменения через CMS (Keystatic/Decap)
  2. Изменения коммитятся в Git
  3. GitHub Actions или Cloudflare Pages автоматически пересобирают сайт (~30-60 сек)
  4. Изменения видны пользователям
code
# .github/workflows/deploy.yml
on:
  push:
    branches: [main]
jobs:
  deploy:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - run: npm ci && npm run build
      - uses: cloudflare/pages-action@v1
        with:
          apiToken: ${{ secrets.CF_API_TOKEN }}
          projectName: company-site
          directory: dist

Итог

Корпоративный сайт на Astro — современная альтернатива WordPress для бизнеса. PageSpeed 100, встроенная безопасность, минимальный хостинг и удобная CMS для редакторов делают этот стек оптимальным для компаний любого размера. Начните с нескольких страниц и расширяйте по мере роста.

Портрет автора Дмитрий Соколов

Senior Frontend Engineer / Tech Writer

Senior Frontend Engineer с 9-летним опытом. Специализируется на Astro.js и JAMstack.

Комментарии

Загрузка комментариев...

Оставить комментарий

Комментарии проходят модерацию перед публикацией. Правила

Рекомендуем к прочтению