Jak dostosować stronę logowania WordPress w 2026 (bez wtyczek)

Jak dostosować stronę logowania WordPress w 2026 (bez wtyczek)

Ostatnio zweryfikowano: 14 października 2026
17 min czytania
Przewodnik
Audytor bezpieczeństwa
Full-stack developer

Domyślny ekran wp-login.php jest rozpoznawalny w trzy sekundy: szare tło, logo WordPressa, generyczny formularz. Dla bloga hobbystycznego to akceptowalne. Dla sklepu, portalu klienta albo wdrożenia agencyjnego pod marką klienta to przeciek wizerunkowy. Redaktor loguje się codziennie; pierwsze wrażenie to nie strona główna, tylko ten ekran.

Ten poradnik pokazuje, jak zbudować white-label logowania wyłącznie hookami WordPressa: login_enqueue_scripts, filtry logo (login_headerurl, login_headertext), login_message, utwardzenie komunikatów błędów oraz decyzję mu-plugin kontra motyw. Bez wtyczki „Custom Login”, bez edycji plików rdzenia, bez CSS, które „ukrywa” URL logowania i udaje bezpieczeństwo.

Materiał jest pod polskie wdrożenia produkcyjne: motyw potomny albo must-use plugin, staging z osobnym kontem testowym, checklista regresji po aktualizacji WordPressa. Kod poniżej używa prefiksu wppoland_ (wppoland.com), żeby nie kolidował z innymi snippetami w tym samym projekcie.

#Co WordPress ładuje na wp-login.php

Zanim podmienisz logo, warto wiedzieć, co rdzeń robi przy żądaniu wp-login.php:

  1. Ładuje wp-admin/css/login.css i zależne style kokpitu (przyciski, formularze).
  2. Uruchamia akcję login_enqueue_scripts - tu dokładasz własne CSS i JS, dokładnie jak wp_enqueue_scripts na froncie.
  3. Renderuje nagłówek z linkiem logo (domyślnie na wordpress.org), formularz, linki „Nie pamiętasz hasła?” / „Zarejestruj się”, stopkę.
  4. Przy błędzie walidacji uruchamia wp_shake_js i pokazuje komunikat z filtra login_errors.
  5. Filtry login_message i login_messages pozwalają wstawić HTML nad formularzem (komunikat po wylogowaniu, info o utrzymaniu, banner SSO).

Kluczowa konsekwencja: strona logowania nie przechodzi przez pełny pipeline motywu frontowego. header.php, bloki FSE i większość enqueue z wp_enqueue_scripts tu nie działają. Stąd osobna akcja login_enqueue_scripts i osobny plik CSS. Jeśli wrzucisz style tylko do style.css motywu, na wp-login.php ich nie będzie.

Druga konsekwencja: aktualizacja WordPressa może zmienić selektory, kolejność skryptów albo markup formularza (np. dodatkowe pola przy 2FA). Branding oparty na hookach przeżywa aktualizację; patchowanie wp-login.php w rdzeniu - nie.

#Jak dodać CSS do logowania przez login_enqueue_scripts

Oficjalny punkt zaczepienia to akcja login_enqueue_scripts. Używaj wp_enqueue_style / wp_enqueue_script, nie wklejaj kilkuset linii CSS w echo wewnątrz login_head, chyba że to naprawdę pięć reguł na logo.

Minimalny enqueue z motywu potomnego:

/**
 * Ładuje style tylko na ekranie logowania.
 */
function wppoland_login_stylesheet() {
	wp_enqueue_style(
		'wppoland-login',
		get_stylesheet_directory_uri() . '/assets/css/style-login.css',
		array(),
		wp_get_theme()->get( 'Version' )
	);
}
add_action( 'login_enqueue_scripts', 'wppoland_login_stylesheet' );

Dlaczego wersja z wp_get_theme()->get( 'Version' ): po deployu CSS nie zostaje w cache przeglądarki pod starym query stringiem. Na mu-pluginie użyj stałej wersji albo filemtime() ścieżki absolutnej.

Przykład style-login.css pod ciemny branding (dostosuj kolory do palety klienta, nie kopiuj ślepo):

body.login {
	background-color: #0d1117;
	background-image: none;
}

.login form {
	background: #161b22;
	border: 1px solid #30363d;
	box-shadow: none;
	border-radius: 8px;
}

.login label,
.login #nav a,
.login #backtoblog a {
	color: #c9d1d9;
}

.wp-core-ui .button-primary {
	background: #238636;
	border-color: #238636;
	text-shadow: none;
	box-shadow: none;
}

.wp-core-ui .button-primary:hover,
.wp-core-ui .button-primary:focus {
	background: #2ea043;
	border-color: #2ea043;
}

.login #login_error,
.login .message,
.login .success {
	border-left-width: 4px;
}

Reguły praktyczne przy CSS logowania:

  • Celuj w klasy, które WordPress faktycznie emituje: body.login, #login, .login form, .wp-core-ui .button-primary, #login_error, .message.
  • Nie chowaj #nav i #backtoblog bez uzgodnienia z klientem - redaktorzy tracą link powrotu na front i odzyskiwanie hasła wygląda „zepsute”.
  • Unikaj display: none na polach formularza „na wszelki wypadek”. Wtyczka 2FA albo passkey doda własne kontrolki; ukrycie ich CSS-em wygląda jak awaria logowania.
  • Testuj kontrast (WCAG) na komunikatach błędów i etykietach - ciemne tło + szary tekst często odpada w audycie dostępności.

Jeśli potrzebujesz fontów klienta, enqueue je tutaj albo hostuj lokalnie w motywie. Trzecia domena na ekranie logowania to zbędny request i kolejny punkt awarii DNS.

#Jak zmienić logo logowania WordPress (CSS i hooki)

WordPress nie ma filtra „podmień plik logo”. Klasyczny wzorzec to CSS na #login h1 a / .login h1 a (background-image) plus dwa filtry na atrybuty linku.

Podmiana grafiki przez login_enqueue_scripts:

function wppoland_login_logo() {
	$logo = get_stylesheet_directory_uri() . '/assets/images/logo-logowania.svg';
	?>
	<style type="text/css">
		#login h1 a,
		.login h1 a {
			background-image: url(<?php echo esc_url( $logo ); ?>);
			background-size: contain;
			background-repeat: no-repeat;
			background-position: center;
			width: 320px;
			height: 80px;
			margin: 0 auto 16px;
		}
	</style>
	<?php
}
add_action( 'login_enqueue_scripts', 'wppoland_login_logo' );

esc_url() na ścieżce assetu to obowiązek, nawet gdy budujesz URL z get_stylesheet_directory_uri(). Logo trzymaj w SVG lub PNG z przezroczystością; JPEG ze zbędnym białym tłem wygląda jak naklejka na ciemnym formularzu.

Domyślny href logo prowadzi na wordpress.org. Filtr login_headerurl zmienia cel:

function wppoland_login_logo_url() {
	return home_url( '/' );
}
add_filter( 'login_headerurl', 'wppoland_login_logo_url' );

Tekst dostępności (title / zawartość dla czytników) ustawia login_headertext (dawniej login_headertitle, przestarzały od WordPressa 5.2; starsze snippety w internecie nadal go cytują):

function wppoland_login_logo_title() {
	return get_bloginfo( 'name' );
}
add_filter( 'login_headertext', 'wppoland_login_logo_title' );

Na instalacjach z osobną domeną kokpitu (np. cms.klient.pl vs www.klient.pl) home_url() nadal wskazuje front, co jest zwykle pożądane. Jeśli logo ma prowadzić do dokumentacji wewnętrznej albo do IdP, zwróć pełny URL HTTPS i przetestuj w oknie incognito.

#Jak dodać komunikat nad formularzem logowania WordPress

Filtr login_message dokłada HTML nad formularzem. Typowe zastosowania produkcyjne:

  • Informacja o oknie utrzymaniowym („Logowanie chwilowo wyłączone poza VPN”).
  • Wskazówka dla redaktorów („Używaj konta firmowego, nie prywatnego Gmaila”).
  • Banner po wylogowaniu albo po resecie hasła (WordPress i tak dokłada własne message classes).
  • Link do SSO / „Zaloguj przez Microsoft”, jeśli IdP jest obok klasycznego hasła.
/**
 * Komunikat nad formularzem logowania.
 *
 * @param string $message Istniejący HTML.
 * @return string
 */
function wppoland_login_message( $message ) {
	$notice = '<p class="message">' . esc_html__(
		'Konto służbowe tylko dla zespołu redakcyjnego. Podejrzenie wycieku hasła zgłoś do IT.',
		'wppoland'
	) . '</p>';

	return $notice . $message;
}
add_filter( 'login_message', 'wppoland_login_message' );

Uwagi wdrożeniowe:

  • Escapuj tekst (esc_html__) albo buduj markup przez wp_kses_post, jeśli musisz wstawić link.
  • Nie zastępuj całego $message ślepo - WordPress dokłada tu własne komunikaty (np. po loggedout=true). Doklejaj albo filtruj warunkowo po $_REQUEST.
  • Klasa .message jest już ostylowana przez login.css; Twój style-login.css powinien ją respektować (kolor tekstu, border-left), inaczej banner znika w tle.

Dla wariantów zależnych od akcji (login, lostpassword, rp) sprawdzaj isset( $_GET['action'] ) albo globalne kontekstowe flagi, zamiast pokazywać ten sam tekst na odzyskiwaniu hasła i na ekranie 2FA.

#Jak bezpiecznie ukryć komunikaty błędów na wp-login

Domyślny komunikat przy złym haśle potrafi zdradzić, że użytkownik o danej nazwie istnieje. To ułatwia enumerację kont. Filtr login_errors pozwala zwrócić jedną, generyczną treść:

function wppoland_login_errors() {
	return __( 'Logowanie nie powiodło się. Sprawdź dane i spróbuj ponownie.', 'wppoland' );
}
add_filter( 'login_errors', 'wppoland_login_errors' );

To utrudnia reconnaissance. To nie jest firewall, rate limiting ani 2FA. Nadal potrzebujesz:

  • limitów prób (serwer, WAF, albo sensowna wtyczka / hardening na poziomie hostingu),
  • silnych haseł i najlepiej drugiego składnika (aplikacja TOTP, klucz sprzętowy),
  • aktualnego WordPressa, motywów i wtyczek,
  • ograniczenia dostępu do wp-admin / XML-RPC tam, gdzie polityka firmy na to pozwala (VPN, IP allowlist, HTTP auth na stagingu).

Najczęstszy antypatern w briefach klientów: „ukryjemy logowanie CSS-em / wyślemy /wp-login.php na 404 w .htaccess i będziemy mieli security”. Dlaczego to nie działa:

  1. Security through obscurity - boty i skanery znają ścieżki domyślne; zmiana URL bez twardej kontroli dostępu tylko psuje bookmarki redaktorów.
  2. CSS nic nie chowa po stronie serwera - display: none na linku „Zaloguj” w menu nie usuwa endpointu. wp-login.php i wp-admin nadal odpowiadają.
  3. Własny slug logowania (wtyczki typu rename login) bywa użyteczny jako warstwa tarcia, ale wymaga utrzymania, testów resetu hasła, WooCommerce My Account, REST i cronów. Samo CSS albo robots.txt Disallow nie zastąpi polityki haseł.
  4. Komunikaty REST / XML-RPC nadal mogą zdradzać istnienie użytkowników niezależnie od brandingu ekranu.

Branding logowania i bezpieczeństwo to dwa tory. White-label poprawia UX i zaufanie. Ochrona konta to capability, rate limit, 2FA i aktualizacje. Nie łącz ich w jeden ticket „zrób ładne i bezpieczne samym CSS”.

Jeśli w projekcie jest wtyczka Two Factor albo passkeys, po wdrożeniu CSS sprawdź ekrany dodatkowych metod (backup codes, security key). Selektor .login form często dostaje więcej pól; zbyt agresywne height / overflow: hidden na #login ucina je w połowie.

#Jak ostylować pola Two Factor na ekranie logowania

Budowanie 2FA w functions.php to zły projekt. Użyj utrzymywanej wtyczki, na przykład Two Factor z katalogu WordPress.org (wersja 0.17.0, ponad 100 000 aktywnych instalacji według API katalogu w październiku 2026), i dopasuj jej pola do brandingu.

Klasy, które ta wtyczka faktycznie emituje na drugim kroku logowania (sprawdzone w kodzie wersji 0.17.0):

  • .two-factor-prompt dla akapitu z instrukcją,
  • input.authcode (z id="authcode") dla pola kodu TOTP, kodu z maila i kodu zapasowego; pole ma inputmode="numeric" i autocomplete="one-time-code", więc nie nadpisuj tych atrybutów skryptem, bo telefon przestanie podpowiadać kod z SMS-a albo menedżera haseł,
  • .backup-methods-wrap dla linków do alternatywnych metod,
  • .two-factor-email-resend dla przycisku ponownej wysyłki kodu mailem.
.login .two-factor-prompt {
	color: #c9d1d9;
}

.login input.authcode {
	letter-spacing: 0.2em;
	text-align: center;
}

.login .backup-methods-wrap a {
	color: #c9d1d9;
}

W starszych poradnikach krążą selektory typu .backup-methods czy .two-factor-methods. W obecnym kodzie wtyczki ich nie ma, więc reguły po prostu nie trafiają. Po każdej aktualizacji wtyczki otwórz drugi krok logowania na stagingu i sprawdź, czy klasy nadal istnieją. Inne wtyczki 2FA i passkey mają własny markup: selektory sprawdzasz w ich kodzie, nie w tym poradniku.

#Co wybrać: mu-plugin czy motyw potomny do logowania

Gdzie trzymać kod? Dwie sensowne lokalizacje, jedna zła.

Motyw potomny (functions.php + assets/css/style-login.css)

  • Zalety: logo i kolory jadą razem z designem frontu; designer zmienia pliki w jednym repozytorium motywu; wersjonowanie przez Version w style.css.
  • Wady: przełączenie motywu (awaria, test A/B, migracja na blokowy) wyłącza branding logowania. Na multisite z różnymi motywami per site kod trzeba powielać albo przenosić wyżej.

Must-use plugin (wp-content/mu-plugins/wppoland-login-branding.php)

  • Zalety: działa niezależnie od aktywnego motywu; idealne na sieć agencyjną i na instalacje, gdzie motyw bywa wymieniany; trudniej „przypadkiem” wyłączyć z kokpitu.
  • Wady: assety (logo, CSS) musisz ładować z katalogu mu-pluginu (plugin_dir_url( __FILE__ )) albo z uploads; deploy mu-pluginów bywa pomijany w workflow „tylko motyw”.

Zła lokalizacja: edycja plików w wp-admin/ albo patch wp-login.php w rdzeniu. Znika przy aktualizacji. Unikaj też „snippetów” wstawianych przez wtyczkę do bazy bez kontroli wersji - przy migracji ze stagingu na produkcję giną albo dublują się.

Wzorzec mu-pluginu z enqueue:

<?php
/**
 * Plugin Name: WPPoland Login Branding
 * Description: White-label wp-login.php niezależnie od motywu.
 * Author: wppoland.com
 */

defined( 'ABSPATH' ) || exit;

add_action( 'login_enqueue_scripts', function () {
	$base = plugin_dir_url( __FILE__ );
	wp_enqueue_style(
		'wppoland-login',
		$base . 'assets/style-login.css',
		array(),
		'2026.09.21'
	);
} );

add_filter( 'login_headerurl', function () {
	return home_url( '/' );
} );

add_filter( 'login_headertext', function () {
	return get_bloginfo( 'name' );
} );

Reguła decyzyjna w briefie: jeśli branding logowania jest częścią produktu klienta (kolory marki, logo kampanii) - motyw potomny. Jeśli to standard agencyjny na wielu instalacjach (to samo logo agencji na stagingach, generyczne błędy, wyłączony shake) - mu-plugin albo wspólny pakiet Composer / prywatne repo wdrażane na wszystkie środowiska.

#Jak brandować wp-login bez łamania aktualizacji rdzenia

Cel: wygląd własny, zachowanie jak w Core. Checklista, która trzyma ten kontrakt:

  1. Tylko hooki publiczne - login_enqueue_scripts, login_headerurl, login_headertext, login_message, login_errors, ewentualnie login_footer. Nie nadpisuj template’ów z wp-login.php przez require skopiowanego pliku.
  2. Nie usuwaj zależnych stylów Core na ślepo - wp_dequeue_style( 'login' ) bez własnego pełnego arkusza psuje dostępność i layout przycisków po aktualizacji.
  3. Efekt trzęsienia możesz wyłączyć świadomie, jeśli klient uważa animację za nieprofesjonalną. Popularny snippet remove_action( 'login_head', 'wp_shake_js', 12 ) nie działa od WordPressa 5.4: rdzeń podpina wp_shake_js pod login_footer, i to warunkowo, wewnątrz funkcji login_header() (widać to w wp-login.php w repozytorium wordpress-develop; w gałęzi 5.3 była tam jeszcze akcja login_head). Stabilna metoda to filtr shake_error_codes, dostępny od wersji 3.0: pusta lista kodów błędów oznacza brak animacji.
add_filter( 'shake_error_codes', '__return_empty_array' );

Filtr należy do publicznego API, więc nie zależy od priorytetu ani od hooka, pod którym rdzeń akurat wypisuje skrypt. Ten przypadek dobrze pokazuje, dlaczego punkt 1 tej listy mówi o hookach publicznych: snippet oparty na wewnętrznym remove_action od sześciu lat nic nie robi, a nadal krąży w poradnikach.

  1. Test regresji po każdej aktualizacji WordPressa: poprawne hasło, złe hasło, puste pola, lost password, reset link z maila, ewentualnie 2FA. Porównaj screenshot stagingu z produkcją.
  2. Języki - jeśli strona jest PL, a kokpit EN (albo odwrotnie), komunikaty z login_errors i login_message trzymaj w textdomainie i ładuj tłumaczenia; hardkodowany polski string na angielskim kokpicie wygląda jak niedokończone wdrożenie.
  3. Multisite - home_url() jest per-site; logo z mu-pluginu może wymagać switch_to_blog albo assetów per blog. Nie zakładaj jednego pliku SVG na całą sieć bez uzgodnienia.
  4. Cache i CDN - HTML logowania zwykle omija page cache, ale CSS z motywu bywa cache’owany agresywnie. Po deployu bump wersji enqueue.

Gdy klient prosi o „całkowicie własny ekran logowania jak w SaaS”, rozważ osobną stronę frontową z formularzem opartym o wp_signon() / custom auth tylko jeśli masz budżet na utrzymanie resetu hasła, nonce, lockout i zgodność z wtyczkami membership. W większości projektów agencyjnych wystarczy ostylowany wp-login.php. Nadmiarowa aplikacja logowania to drugi produkt do łatania przy każdej luce w uwierzytelnianiu.

#Jakich błędów unikać przy customizacji logowania WordPress

Poza regułami z listy wyżej najczęściej wracają te:

  1. Ciężkie bundle frontu ładowane na ekranie logowania. Arkusz logowania ma być mały i dotyczyć tylko wp-login.php.
  2. Ukryty adres logowania nazywany “bezpieczeństwem”, podczas gdy na koncie nadal siedzi login admin i hasło password123.
  3. Trzy wtyczki do customizacji logowania nałożone na te same hooki. Każda nadpisuje poprzednią i nikt nie wie, która wygrywa.
  4. Sekrety i klucze API w pliku CSS logowania. Ten plik jest publiczny.

Zmiana sluga logowania (osobną wtyczką) to odrębna decyzja. Może ograniczyć przypadkowe boty, ale psuje zakładki i część checklist wdrożeniowych. Branding i zmiana sluga są od siebie niezależne. Jeśli zmieniasz ścieżkę logowania, wpisz nowy adres do paczki przekazania projektu i do notatek w menedżerze haseł klienta. Zgłoszenia “logowanie nie działa” po zmianie sluga są kosztowne, a da się ich uniknąć.

#Jak dostosować logowanie WooCommerce i wtyczek membership

Strony konta WooCommerce i bloki logowania w checkoucie mają inny markup niż wp-login.php. CSS ekranu logowania nie zmieni wyglądu formularzy na my-account. Albo zostawiasz standardowe formularze Woo, albo ładujesz osobny arkusz na tych szablonach. Mieszanie obu w style-login.css zostawia martwe reguły i myli kolejnego developera.

Ten sam podział dotyczy LearnDash, MemberPress i podobnych produktów: najpierw ustal, przez który adres klienci naprawdę się logują, potem brandujesz tę powierzchnię. Typowy błąd agencji to dopieszczony wp-login.php, podczas gdy klienci widzą wyłącznie modal na froncie, który w iframe nadal pokazuje logo WordPressa.

#Jakie hooki strony logowania WordPress są dostępne od której wersji

Tabela poniżej pochodzi z bloków @since w pliku src/wp-login.php w repozytorium wordpress-develop (stan na październik 2026, aktualne wydanie to WordPress 7.1.3). Przydaje się, gdy klient trzyma starą instalację albo gdy snippet z forum używa hooka, którego jeszcze nie ma lub który jest już wycofany.

HookTypOd wersjiDo czego służy
login_headerurlfiltr2.1.0adres linku logo
login_messagefiltr2.1.0HTML nad formularzem
login_errorsfiltr2.1.0treść błędów
login_messagesfiltr2.5.0komunikaty informacyjne
login_redirectfiltr3.0.0cel przekierowania po logowaniu
shake_error_codesfiltr3.0.0kody błędów, które trzęsą formularzem
login_enqueue_scriptsakcja3.1.0CSS i JS ekranu logowania
login_footerakcja3.1.0treść w stopce
login_initakcja3.2.0start obsługi żądania
login_body_classfiltr3.5.0klasy elementu body
login_headerakcja4.6.0treść zaraz po otwarciu body
login_titlefiltr4.9.0zawartość znacznika title
login_link_separatorfiltr4.9.0separator linków pod formularzem
login_headertextfiltr5.2.0tekst linku logo
login_site_html_linkfiltr5.7.0link powrotu na stronę w stopce
login_display_language_dropdownfiltr5.9.0czy pokazać wybór języka
login_language_dropdown_argsfiltr5.9.0argumenty listy języków

login_headertitle (od 2.1.0) jest od wersji 5.2.0 oznaczony jako przestarzały i przechodzi przez apply_filters_deprecated, więc przy włączonym WP_DEBUG zostawia ostrzeżenie w logu. Jeśli widzisz go w motywie klienta, zamień go na login_headertext.

#Jak zmienić tytuł, klasę body i wybór języka na wp-login.php

Cztery filtry z tabeli załatwiają drobne prośby z briefów bez dotykania CSS:

// Krótszy tytuł karty: nazwa ekranu i nazwa witryny.
add_filter( 'login_title', function ( $login_title, $title ) {
	return $title . ' | ' . get_bloginfo( 'name', 'display' );
}, 10, 2 );

// Własna klasa na body, żeby reguły logowania nie kolidowały z innymi arkuszami.
add_filter( 'login_body_class', function ( $classes ) {
	$classes[] = 'wppoland-login';
	return $classes;
} );

// Link w stopce prowadzi do strony pomocy zamiast na stronę główną.
add_filter( 'login_site_html_link', function () {
	return sprintf(
		'<a href="%s">%s</a>',
		esc_url( home_url( '/pomoc/' ) ),
		esc_html__( 'Pomoc dla redakcji', 'wppoland' )
	);
} );

// Bez listy języków pod formularzem.
add_filter( 'login_display_language_dropdown', '__return_false' );

Szczegóły, które wychodzą dopiero w kodzie rdzenia:

  • Domyślny tytuł składa się z nazwy ekranu, nazwy witryny i słowa WordPress na końcu. W trybie odzyskiwania rdzeń dopisuje prefiks trybu, zanim wywoła filtr. Funkcja, która składa tytuł od zera z $title, ten prefiks gubi, więc administrator nie widzi na karcie, że jest w trybie odzyskiwania. Jeśli to ma znaczenie, modyfikuj $login_title zamiast go zastępować.
  • Lista języków pojawia się tylko wtedy, gdy na serwerze jest zainstalowany co najmniej jeden dodatkowy pakiet językowy, i nigdy w okienku ponownego logowania w kokpicie. Ukrycie jej nie zmienia języka konta: po zalogowaniu i tak obowiązuje ustawienie z profilu.
  • login_site_html_link podmienia cały element <a>, więc sam odpowiadasz za esc_url i escapowanie tekstu.
  • Link do polityki prywatności pod formularzem pochodzi z the_privacy_policy_link() i pojawia się, gdy strona polityki jest ustawiona w kokpicie. Nie ukrywaj go CSS-em na stronach, które zbierają dane przez formularz rejestracji.

#Jakie nagłówki bezpieczeństwa WordPress wysyła na wp-login.php

Zanim dopiszesz własne nagłówki albo meta tagi do ekranu logowania, sprawdź, co rdzeń już robi. Według default-filters.php i wp-login.php:

  • send_frame_options_header() na akcji login_init (od 3.1.3) wysyła X-Frame-Options: SAMEORIGIN, a od WordPressa 6.9 ta sama funkcja dokłada Content-Security-Policy: frame-ancestors 'self'. Ekranu logowania nie da się osadzić w ramce na obcej domenie.
  • wp_admin_headers() na login_init (od 4.9) wysyła Referrer-Policy: strict-origin-when-cross-origin; filtr admin_referrer_policy pozwala zmienić wartość.
  • wp_robots_sensitive_page() (od 5.7) dodaje do meta robots noindex i noarchive, a wypisuje je wp_robots na login_head.
  • wp_strict_cross_origin_referrer() (od 5.7) dodaje meta referrer z tą samą polityką.
  • wp_site_icon na login_head wypisuje faviconę z ustawienia Ikona witryny.

Wniosek praktyczny: osobny snippet z meta robots noindex albo z linkiem do favicony na login_head tylko dubluje znaczniki. Nagłówka X-XSS-Protection nie dodawaj wcale. MDN opisuje go jako niestandardowy i przestarzały, zaznacza, że w niektórych przypadkach sam tworzy podatności XSS na bezpiecznych stronach, i zaleca Content-Security-Policy. Nagłówki dla całej domeny (HSTS, CSP) trzymaj w konfiguracji serwera albo CDN, nie w PHP podpiętym pod login_init, bo wtedy obejmują też wp-admin i REST.

#Jak przetestować branding logowania na stagingu

Przejdź po kolei na kopii produkcyjnej:

  1. Wgraj CSS i logo; odśwież wp-login.php z pominięciem cache (okno incognito).
  2. Kliknij logo - lądujesz na froncie klienta, nie na wordpress.org.
  3. Zaloguj się poprawnym kontem; wyloguj; zaloguj złym hasłem - komunikat jest generyczny.
  4. Sprawdź „Nie pamiętasz hasła?” i mail resetu na środowisku ze skonfigurowanym SMTP.
  5. Jeśli jest 2FA - przejdź pełną ścieżkę raz na desktopie i raz na telefonie.
  6. Przełącz tymczasowo motyw na Twenty Twenty-Something: jeśli branding znika, a miał być globalny, przenieś kod do mu-pluginu.
  7. Zapisz w README projektu ścieżki plików i listę filtrów - kolejny deweloper nie szuka „magii” w pięciu wtyczkach snippet.

Po akceptacji klienta zrób ten sam smoke test na produkcji zaraz po deployu, nie „jutro”.

#Podsumowanie

White-label wp-login.php w 2026 to zestaw publicznych hooków, nie patch rdzenia i nie wtyczka z tysiącem opcji w kokpicie. Enqueue CSS przez login_enqueue_scripts, podmień logo i login_headerurl, doklej sensowny login_message, utwardź login_errors. Trzymaj kod w motywie potomnym albo mu-pluginie - nigdy w plikach Core. Nie udawaj zabezpieczenia ukryciem URL w CSS.

Gdy porządkujesz ryzyka wokół kont i kokpitu szerzej niż branding, zobacz audyt bezpieczeństwa WordPress.

Następny krok

Przekuj artykuł w realne wdrożenie

Pod tym wpisem dokładam linki, które domykają intencję użytkownika i prowadzą dalej w strukturze serwisu.

Powiązany klaster

Sprawdź inne usługi WordPress i bazę wiedzy

Wzmocnij swój biznes dzięki profesjonalnemu wsparciu technicznemu w kluczowych obszarach ekosystemu WordPress.

Jak zmienić logo logowania WordPress bez wtyczki?#
Podepnij funkcję pod login_enqueue_scripts, wypisz CSS dla #login h1 a z własnym obrazkiem z motywu potomnego albo mu-pluginu, a filtrem login_headerurl skieruj link logo na stronę główną.
Dlaczego remove_action dla wp_shake_js nie wyłącza trzęsienia?#
Od WordPressa 5.4 rdzeń podpina wp_shake_js pod login_footer, nie pod login_head. Stabilna metoda to filtr shake_error_codes zwracający pustą tablicę.
Gdzie trzymać kod brandingu ekranu logowania?#
W motywie potomnym, gdy branding jest częścią produktu klienta, albo w must-use pluginie, gdy ma przetrwać zmianę motywu. Nigdy w plikach rdzenia.
Czy ukrycie komunikatów błędów chroni przed brute force?#
Nie. Generyczny komunikat utrudnia enumerację kont, ale nadal potrzebujesz limitów prób na serwerze lub WAF, silnych haseł i 2FA dla administratorów.
Czy trzeba dodawać meta robots noindex na wp-login.php?#
Nie. Od WordPressa 5.7 rdzeń sam dodaje noindex i noarchive na ekranie logowania, a własny snippet tylko dubluje znacznik.

Potrzebujesz FAQ dopasowanego do branży i rynku? Przygotujemy wersję pod Twoje cele biznesowe.

Porozmawiajmy

Polecane artykuły