Серверный рендеринг

fullPage.js — это библиотека для создания полноэкранных скролл-сайтов с плавной навигацией между секциями и слайдерами. Обычно её используют в браузере, управляя DOM напрямую, но при серверном рендеринге (SSR) возникают особенности, которые важно учитывать.

Подготовка проекта к SSR

При серверном рендеринге важно понимать, что на сервере нет окна (window) и документа (document). fullPage.js активно взаимодействует с DOM, создавая обёртки для секций, добавляя навигационные элементы и прослушивая события скролла. Это значит, что инициализация fullPage.js на сервере напрямую вызовет ошибки типа ReferenceError: window is not defined.

Для обхода этой проблемы применяют условную инициализацию:

if (typeof window !== 'undefined') {
    import('fullpage.js').then(({ default: fullpage }) => {
        new fullpage('#fullpage', {
            autoScrolling: true,
            navigation: true,
            anchors: ['firstPage', 'secondPage', 'thirdPage'],
        });
    });
}

Здесь проверка typeof window !== 'undefined' гарантирует, что код fullPage.js выполнится только в браузере.

Интеграция с фреймворками

Next.js

В Next.js компоненты можно разделять на динамические и обычные. fullPage.js удобно подключать через динамический импорт с опцией ssr: false:

import dynamic from 'next/dynamic';

const FullpageWrapper = dynamic(() => import('../components/FullpageComponent'), {
    ssr: false
});

export default function Home() {
    return <FullpageWrapper />;
}

Внутри FullpageComponent используется стандартная инициализация fullPage.js через useEffect:

import { useEffect } from 'react';
import fullpage from 'fullpage.js';

export default function FullpageComponent() {
    useEffect(() => {
        new fullpage('#fullpage', {
            autoScrolling: true,
            navigation: true
        });

        return () => fullpage.destroy('all');
    }, []);

    return (
        <div id="fullpage">
            <div className="section">Section 1</div>
            <div className="section">Section 2</div>
            <div className="section">Section 3</div>
        </div>
    );
}

useEffect выполняется только на клиенте, поэтому серверный рендеринг не вызывает ошибок.

Nuxt.js / Vue 3

Для Vue-проектов с SSR библиотеку подключают через onMounted или динамический импорт:

<template>
  <div id="fullpage">
    <section class="section">Section 1</section>
    <section class="section">Section 2</section>
  </div>
</template>

<script setup>
import { onMounted } from 'vue';

onMounted(async () => {
  const fullpage = (await import('fullpage.js')).default;
  new fullpage('#fullpage', {
    autoScrolling: true,
    navigation: true
  });
});
</script>

onMounted гарантирует, что DOM полностью создан на клиенте до инициализации fullPage.js.

Оптимизация рендеринга

  1. Минимизация блокирующего JS fullPage.js тяжеловесен, поэтому желательно загружать его асинхронно и только для страниц с полноэкранным скроллом. Для остальных страниц можно использовать статическую разметку без инициализации.

  2. Разделение секций на компоненты Каждую секцию удобно выносить в отдельный компонент. Это позволяет серверу рендерить базовую структуру страниц с контентом, а fullPage.js управляет только навигацией и анимациями на клиенте.

  3. Отложенная инициализация Иногда полезно инициализировать fullPage.js после полной загрузки изображений или данных через window.addEventListener('load', ...). Это снижает вероятность дерганий и визуальных артефактов.

Особенности навигации и anchor-ссылок

fullPage.js позволяет привязывать секции к anchor-строкам. При SSR важно генерировать разметку секций с правильными id, чтобы при первичном рендере на сервере ссылки уже работали. Например:

<div id="fullpage">
  <div class="section" data-anchor="home">Home</div>
  <div class="section" data-anchor="about">About</div>
</div>

Это позволяет SEO-ботам индексировать страницы и сохраняет корректность URL при клиентской навигации.

Интеграция с динамическими данными

При SSR данные часто загружаются заранее. Для fullPage.js важно, чтобы контент секций был уже на странице при инициализации. Если данные подгружаются асинхронно после mount, необходимо обновить fullPage.js, например, с помощью методов fullpage.reBuild():

// После добавления или удаления секций
fullpage_api.reBuild();

Проблемы и ограничения SSR

  • No window/document: Все операции с DOM должны выполняться только на клиенте.
  • SEO и индексация: Серверный рендер помогает, но динамически создаваемые слайды fullPage.js без контента могут остаться пустыми.
  • Проверка производительности: При большом количестве секций лучше использовать lazy-load изображений и ресурсов, чтобы не перегружать клиент.

Рекомендации по совместимости

  • Использовать последнюю версию fullPage.js с поддержкой модульного импорта (ES modules).
  • Проверять инициализацию на всех платформах: desktop, mobile, планшеты.
  • Для анимаций и переходов применять CSS3, минимизируя JavaScript-анимации при SSR.

Полноэкранный скролл с fullPage.js при серверном рендеринге требует продуманного разделения клиентского и серверного кода, корректной генерации секций и безопасной инициализации через динамический импорт или хуки useEffect / onMounted. Это обеспечивает совместимость с SSR-фреймворками и улучшает производительность и SEO.