Maintance mode w aplikacjach Next.js
Autor Agnieszka Wojtas
Autor Agnieszka Wojtas
Podczas tworzenia i zarządzania projektem ważne jest uwzględnienie momentów, kiedy aplikacja będzie niedostępna z powodu konserwacji. W przypadku systemów CMS, takich jak np. WordPress, istnieją rozmaite wtyczki, umożliwiające zasłonę witryny podczas wprowadzania zmian lub testowania nowych funkcjonalności.
Ale jak zaimplementować maintenance mode w Next.js? Czy jest to równie proste, co kilkuminutowa konfiguracja wtyczki w WordPress’ie?
Oczywiście, że tak!
Podczas poszukiwań rozwiązania dla trybu konserwacji w aplikacjach Next.js natknęłam się na brak dostępnych narzędzi, które spełniałyby moje oczekiwania pod względem szybkości, elastyczności i łatwości użycia.
Na początek tworzymy plik route.ts w głównym folderze aplikacji app->api, który będzie odpowiedzialny za obsługę żądania dla naszego maintenance mode:
import { serialize } from "cookie";
export async function POST(request: Request, params: { slug: string }) {
const data: { password: string } = await request.json();
const password = data.password;
const expirationTime = 4 * 60 * 60; // 4 hours
const cookie = serialize(process.env.PASSWORD_COOKIE_NAME!, "true", {
httpOnly: true,
path: "/",
maxAge: expirationTime,
});
if (process.env.PAGE_PASSWORD !== password) {
return new Response("incorrect password", {
status: 401,
});
}
return new Response("password correct", {
status: 200,
headers: {
"Set-Cookie": cookie,
},
});
}
Kolejnym krokiem będzie stworzenie komponentu, którego wygląd, użytkownik zobaczy bezpośrednio po wejściu na stronę. Poniżej przykładowy wzór, który można dostosować do potrzeb klienta:
"use client";
import React, { useState, useEffect } from "react";
const PasswordPromptDialog = () => {
const [password, setPassword] = useState("");
const [passwordIncorrect, setPasswordIncorrect] = useState(false);
const [noPassword, setNoPassword] = useState(false);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
const request = await fetch(`/api`, {
body: JSON.stringify({ password }),
headers: { "Content-Type": "application/json" },
method: "post",
});
if (password) {
if (request.status !== 200) {
return setNoPassword(false), setPasswordIncorrect(true);
} else {
window.location.reload();
}
} else {
return setPasswordIncorrect(false), setNoPassword(true);
}
};
useEffect(() => {
setPassword("");
}, [passwordIncorrect]);
return (
<div>
<p>Maintenance mode is enabled!</p>
<div>
<form onSubmit={handleSubmit}>
<label htmlFor="password">Password:</label>
<input
type="password"
id="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
/>
<button type="submit">
Log In
</button>
</form>
{noPassword && (
<p
style={{
color: "red",
fontSize: "14px",
}}
>
Enter the password.
</p>
)}
{passwordIncorrect && (
<p
style={{
color: "red",
fontSize: "14px",
}}
>
The entered password is incorrect.
</p>
)}
</div>
</div>
);
};
export default PasswordPromptDialog;
Ostatnim krokiem, będzie wywołanie komponentu PasswordPromptDialog w pliku layout.tsx w następujący sposób:
import { cookies } from "next/headers";
import PasswordPromptDialog from "@/components/PasswordPromptDialog/PasswordPromptDialog";
import "@/styles/globals.scss";
export default async function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
const isMaintenanceMode = process.env.MAINTENANCE_MODE === "true";
if (isMaintenanceMode) {
const cookieStore = cookies();
const loginCookies = cookieStore.get(
`${process.env.PASSWORD_COOKIE_NAME!}`
);
const isLoggedIn = !!loginCookies?.value;
if (!isLoggedIn) {
return (
<html lang="pl">
<body>
<PasswordPromptDialog />;
</body>
</html>
);
}
}
return (
<html lang="pl">
<body>{children}</body>
</html>
);
}
Na sam koniec, wystarczy jeszcze dodać poniższe zmienne środowiskowe do projektu (.env) z ustalonymi wartościami:
MAINTENANCE_MODE=FALSE
PASSWORD_COOKIE_NAME=authorized
SEARCH_QUERY_NAME=password
PAGE_PASSWORD=YourPasswordForWebsite
Wdrożenie trybu konserwacji w aplikacjach Next.js wbrew pozorom jest kluczowe podczas tworzenia i zarządzania projektem. Choć systemy CMS, takie jak WordPress, oferują różnorodne wtyczki umożliwiające zasłonięcie witryny podczas prac konserwacyjnych, implementacja maintenance mode w Next.js może wydawać się bardziej wymagająca.
Jednakże, dzięki przedstawionemu rozwiązaniu, które opiera się na wykorzystaniu cookies do przechowywania informacji o autentykacji, tworzenie trybu konserwacji staje się równie prostą operacją, co konfiguracja wtyczki w systemie CMS. Dzięki zastosowaniu cookies, nie tylko zachowujemy elastyczność i szybkość działania, ale również zwiększamy poziom bezpieczeństwa poprzez uniemożliwienie odczytu danych przez skrypty JavaScript (ustawienie opcji httpOnly).
Podsumowując, powyższe rozwiązanie pozwala na szybką i łatwą implementację trybu konserwacji w aplikacjach Next.js, jednocześnie dając użytkownikowi pełną kontrolę nad wyglądem "zasłony" i autentykacją. Dodatkowo, możliwość szybkiego przełączania trybu konserwacji za pomocą zmiany wartości zmiennej środowiskowej sprawia, że nasze rozwiązanie jest niezwykle elastyczne i dostosowane do różnych potrzeb projektowych.
Wtyczka Medusa Tolgee do obsługi wielu języków integruje platformę eCommerce Medusa z Tolgee, platformą lokalizacyjną typu open-source, oferując łatwe rozwiązanie do zarządzania tłumaczeniami...
W tym poradniku opiszę, jak działa Meilisearch i przedstawię praktyczne przykłady jego integracji z Medusa.js.