Standard WordPress-innloggingsskjerm (wp-login.php) er gjenkjennelig, men den signaliserer «generisk installasjon». Når et byrå leverer til en kunde, er WordPress-logoen på innloggingssiden en merkevarelekkasje.
White-label av innlogging er vanlig i klientprosjekter. Denne guiden viser hvordan du tilpasser opplevelsen med functions.php eller - bedre - en must-use-plugin, slik at skjermen føles som en del av produktet. Offisiell referanse: login_enqueue_scripts, login_headerurl og login_errors.
Hvorfor tilpasse WordPress-innloggingssiden for kunder
Tre grunner som dukker opp i support:
- Tillit - redaktører logger inn hver uke. En merket skjerm reduserer «er dette riktig side?»-spørsmål.
- Sikkerhet - generiske feilmeldinger og færre hint om brukernavn gjør enumerering vanskeligere.
- Konsistens - samme farger og logo som frontend gjør at CMS-et føles ferdig, ikke midlertidig.
På et norsk forlagsprosjekt med tre redaktører og én ekstern korrekturleser forsvant «hvilken URL logger jeg inn på?» etter at logo, favicon-hint i nettlesertittel og login_headertext pekte til kundens merkevare. Det var femten linjer PHP, ikke en plugin-suite.
Hva WordPress laster på wp-login.php
Før du bytter logo, er det nyttig å vite hva kjernen gjør når wp-login.php blir forespurt:
- Den laster
wp-admin/css/login.cssog dashbordstilene den avhenger av (knapper, skjemaer). - Den kjører
login_enqueue_scripts, der du legger til egen CSS og JS, akkurat somwp_enqueue_scriptspå frontend. - Den skriver ut toppen med logolenken (til wordpress.org som standard), skjemaet, lenkene for glemt passord og registrering, og bunnteksten.
- Ved en valideringsfeil legger den til ristescriptet og viser meldingen fra filteret
login_errors. - Filtrene
login_messageoglogin_messageslar deg legge HTML over skjemaet (melding etter utlogging, vedlikeholdsvarsel, SSO-banner).
Den viktigste konsekvensen: innloggingssiden går ikke gjennom temaets frontend-løp. header.php, maler i et blokktema og de fleste wp_enqueue_scripts-callbacks kjører ikke der. Derfor finnes en egen enqueue-handling, og derfor trenger login-stilene en egen fil. Regler som bare ligger i temaets style.css, når aldri wp-login.php.
Den andre konsekvensen: en WordPress-oppdatering kan endre selektorer, rekkefølgen på script eller markup i skjemaet (ekstra felt fra en 2FA-plugin, for eksempel). Merkevare bygget på hooks overlever oppdateringen; en patchet wp-login.php i kjernen gjør det ikke.
Must-use-plugin eller functions.php for innloggingskode
Ikke legg login-CSS i barne-temaets functions.php alene. Når kunden bytter skin, forsvinner white-label. Bruk wp-content/mu-plugins/wppoland-login.php (eller tilsvarende) slik at tilpasningen overlever temabytte og forblir under byråkontroll.
<?php
/**
* Plugin Name: Login Branding
* Description: White-label av wp-login.php uavhengig av aktivt tema.
*/
defined( 'ABSPATH' ) || exit;
add_action( 'login_enqueue_scripts', function () {
wp_enqueue_style(
'site-login',
plugin_dir_url( __FILE__ ) . 'assets/style-login.css',
array(),
'2026.10.14'
);
} );
add_filter( 'login_headerurl', function () {
return home_url( '/' );
} );
add_filter( 'login_headertext', function () {
return get_bloginfo( 'name' );
} );En beslutningsregel for briefen: hvis innloggingsmerket er en del av kundens produkt (merkefarger, kampanjelogo), hører koden hjemme i barnetemaet. Hvis det er en byråstandard på mange installasjoner (samme byrålogo på alle staging-miljøer, generiske feil, ingen risting), bruk en must-use-plugin eller en felles Composer-pakke som deployes til alle miljøer. Ikke legg koden i en snippet-plugin som lagrer PHP i databasen: uten versjonskontroll forsvinner eller dobles den når staging flyttes til produksjon.
1. Bytte logo på WordPress-innloggingssiden
Bytt ut WordPress-«W» med kundens logo via CSS på #login h1 a.
function wppoland_login_logo() { ?>
<style type="text/css">
#login h1 a, .login h1 a {
background-image: url(<?php echo esc_url( get_stylesheet_directory_uri() . '/images/kunde-logo.svg' ); ?>);
height: 65px;
width: 320px;
background-size: contain;
background-repeat: no-repeat;
padding-bottom: 30px;
}
</style>
<?php }
add_action( 'login_enqueue_scripts', 'wppoland_login_logo' );Bruk esc_url rundt URI. SVG eller PNG med transparent bakgrunn fungerer best på både lys og mørk flate.
Standardlenken går til WordPress.org. Pek den til forsiden:
function wppoland_login_logo_url() {
return home_url( '/' );
}
add_filter( 'login_headerurl', 'wppoland_login_logo_url' );
function wppoland_login_logo_title() {
return get_bloginfo( 'name' );
}
add_filter( 'login_headertext', 'wppoland_login_logo_title' );login_headertext erstatter det gamle filteret login_headertitle, som har vært foreldet siden WordPress 5.2.
Hvordan legge til en melding over innloggingsskjemaet i WordPress
Filteret login_message legger HTML over skjemaet. Typisk bruk i produksjon:
- Et vedlikeholdsvarsel («Innlogging utenfor VPN er stengt i kveld»).
- Et hint til redaktører («Bruk jobbkontoen, ikke en privat konto»).
- Et banner etter utlogging eller tilbakestilt passord (kjernen legger også inn egne meldingsklasser der).
- En lenke til SSO når identitetsleverandøren står ved siden av vanlige passord.
/**
* Melding over innloggingsskjemaet.
*
* @param string $message Eksisterende HTML.
* @return string
*/
function wppoland_login_message( $message ) {
$notice = '<p class="message">' . esc_html__(
'Kun kontoer for redaksjonen. Meld fra til IT ved mistanke om passordlekkasje.',
'wppoland'
) . '</p>';
return $notice . $message;
}
add_filter( 'login_message', 'wppoland_login_message' );Merknader:
- Escape teksten (
esc_html__), eller bygg markup medwp_kses_posthvis du trenger en lenke. - Ikke erstatt
$messagei blinde. Kjernen legger egne meldinger der (etterloggedout=true, for eksempel). Legg din tekst foran, eller filtrer betinget på forespørselen. - Klassen
.messageer allerede stylet avlogin.css. Dinstyle-login.cssmå respektere den (tekstfarge, venstre kant), ellers forsvinner banneret i bakgrunnen.
For tekst som avhenger av handlingen (login, lostpassword, rp), sjekk $_GET['action'] i stedet for å vise samme melding ved passordgjenoppretting og på 2FA-steget.
2. Hvordan legge til egen CSS på wp-login.php
Den grå standardbakgrunnen er sjelden merkevare. Last en dedikert fil bare på innloggingssiden:
function wppoland_login_stylesheet() {
wp_enqueue_style(
'wppoland-custom-login',
get_stylesheet_directory_uri() . '/style-login.css',
array(),
'2026.1'
);
}
add_action( 'login_enqueue_scripts', 'wppoland_login_stylesheet' );Eksempel style-login.css:
body.login {
background-color: #0d1117;
display: flex;
align-items: center;
justify-content: center;
}
.login form {
background: #161b22;
border: 1px solid #30363d;
box-shadow: none;
border-radius: 8px;
}
.login label {
color: #c9d1d9;
}
.wp-core-ui .button-primary {
background: #238636;
border-color: rgba(27, 31, 35, 0.15);
}
.login #backtoblog a,
.login #nav a {
color: #8b949e;
}Test både lys og mørk preferanse hvis kunden har offentlig frontend i lys modus - kontrast på knapper og feilmeldinger er det som vanligvis glipper.
CSS-selektorer for innloggingssiden
| Element | Selektor | Merk |
|---|---|---|
| Bakgrunn | body.login | Unngå tunge bakgrunnsvideoer |
| Skjema | .login form | Kant, radius, skygge |
| Primærknapp | .wp-core-ui .button-primary | Hover-tilstand også |
| Lenker | #nav a, #backtoblog a | Synlige på mørk flate |
| Feilmelding | #login_error | Lesbar uten å skrike |
| Language switcher | .language-switcher | Ofte glemt på flerspråklige installasjoner |
3. Hvordan endre feilmeldingen ved mislykket innlogging
Som standard kan WordPress avsløre om et brukernavn finnes. Det hjelper brute force. Tving en generisk melding:
function wppoland_login_errors() {
return 'Innlogging mislyktes. Sjekk brukernavn og passord.';
}
add_filter( 'login_errors', 'wppoland_login_errors' );Dette er ikke erstatning for rate limiting, 2FA eller sterke passord. Det er én lag i dybden. Kombiner med:
- Unikt administratorbrukernavn (ikke
admin) - Begrensning av innloggingsforsøk (plugin eller serverregel)
- HTTPS overalt
- Eventuelt bytte av innloggings-URL bare hvis du også sikrer resten av overflaten
4. Hvordan fjerne risteeffekten ved feil passord
Ved feil rister skjemaet. Noen klienter synes det er uprofesjonelt eller distraherende:
Snutten de fleste guider fortsatt kopierer, remove_action( 'login_head', 'wp_shake_js', 12 ), har ikke gjort noe siden WordPress 5.4. Kjernen kobler nå wp_shake_js til login_footer, og bare betinget, inne i login_header(). Det står i wp-login.php i wordpress-develop-repoet; 5.3-grenen brukte fortsatt login_head. Den stabile metoden er filteret shake_error_codes, tilgjengelig siden 3.0: en tom liste med feilkoder betyr ingen animasjon.
add_filter( 'shake_error_codes', '__return_empty_array' );Filteret er offentlig API, så det avhenger ikke av prioritet eller av hvilken hook kjernen tilfeldigvis skriver ut scriptet fra.
5. Flere login-hooks i WordPress
Tabellen kommer fra @since-taggene i src/wp-login.php i wordpress-develop-repoet (oktober 2026, gjeldende versjon WordPress 7.1.3). Den er nyttig når en kunde kjører en gammel installasjon, eller når en forumsnutt bruker en hook som ikke finnes ennå eller allerede er foreldet.
| Hook | Type | Siden | Bruk |
|---|---|---|---|
login_headerurl | filter | 2.1.0 | URL for logolenken |
login_message | filter | 2.1.0 | HTML over skjemaet |
login_errors | filter | 2.1.0 | feiltekst |
login_messages | filter | 2.5.0 | informasjonsmeldinger |
login_redirect | filter | 3.0.0 | mål for omdirigering etter innlogging |
shake_error_codes | filter | 3.0.0 | feilkoder som får skjemaet til å riste |
login_enqueue_scripts | handling | 3.1.0 | CSS og JS for innloggingssiden |
login_footer | handling | 3.1.0 | utskrift i bunnen |
login_init | handling | 3.2.0 | start på behandlingen av forespørselen |
login_body_class | filter | 3.5.0 | klasser på body |
login_header | handling | 4.6.0 | utskrift rett etter at body åpnes |
login_title | filter | 4.9.0 | innholdet i title-taggen |
login_link_separator | filter | 4.9.0 | skilletegn mellom lenkene under skjemaet |
login_headertext | filter | 5.2.0 | tekst i logolenken |
login_site_html_link | filter | 5.7.0 | lenke tilbake til nettstedet i bunnen |
login_display_language_dropdown | filter | 5.9.0 | om språkvelgeren vises |
login_language_dropdown_args | filter | 5.9.0 | argumenter til språklisten |
login_headertitle (siden 2.1.0) er foreldet siden 5.2.0 og går gjennom apply_filters_deprecated, så med WP_DEBUG på legger den igjen en melding i loggen. Bruker kundens tema den fortsatt, bytt til login_headertext.
Skjule språkvelgeren på innloggingssiden
add_filter( 'login_display_language_dropdown', '__return_false' );Språklisten vises bare når minst én ekstra språkpakke er installert, og aldri i dashbordets vindu for ny innlogging. Å skjule den endrer ikke kontospråket: etter innlogging gjelder innstillingen i profilen.
Legge til body-klasse med login_body_class
function wppoland_login_body_class( $classes ) {
$classes[] = 'wppoland-branded-login';
return $classes;
}
add_filter( 'login_body_class', 'wppoland_login_body_class' );Kortere fanetittel med login_title
add_filter( 'login_title', function ( $login_title, $title ) {
return $title . ' | ' . get_bloginfo( 'name', 'display' );
}, 10, 2 );Standardtittelen består av skjermnavnet, nettstedsnavnet og ordet WordPress til slutt. I gjenopprettingsmodus legger kjernen til et prefiks før filteret kjøres. En callback som bygger tittelen bare fra $title, mister det prefikset, og administratoren ser ikke lenger på fanen at nettstedet er i gjenopprettingsmodus. Endre $login_title i stedet for å erstatte den hvis det betyr noe.
Bytte tilbakelenken med login_site_html_link
add_filter( 'login_site_html_link', function () {
return sprintf(
'<a href="%s">%s</a>',
esc_url( home_url( '/hjelp/' ) ),
esc_html__( 'Hjelp for redaktører', 'wppoland' )
);
} );Filteret erstatter hele <a>-elementet, så escaping av URL og tekst er ditt ansvar. Lenken til personvernerklæringen under skjemaet kommer fra the_privacy_policy_link() og vises når en personvernside er valgt. Ikke skjul den med CSS på nettsteder som samler inn data gjennom et registreringsskjema.
Omdirigering etter innlogging basert på rolle
function wppoland_login_redirect( $redirect_to, $request, $user ) {
if ( isset( $user->roles ) && is_array( $user->roles ) ) {
if ( in_array( 'shop_manager', $user->roles, true ) ) {
return admin_url( 'edit.php?post_type=shop_order' );
}
}
return $redirect_to;
}
add_filter( 'login_redirect', 'wppoland_login_redirect', 10, 3 );Ikke hardkod kunde-URL-er uten admin_url() / home_url() - det knuser staging.
6. Hvordan style 2FA og passkeys på innloggingssiden
Passord alene er sjelden nok for administratorer. Du bygger sjelden 2FA fra bunnen i functions.php. Bruk en vedlikeholdt løsning og style feltene. Two Factor fra WordPress.org-katalogen (versjon 0.17.0, over 100 000 aktive installasjoner ifølge katalogens API i oktober 2026) skriver ut disse klassene på andre innloggingssteg, hentet fra koden i 0.17.0:
.two-factor-promptfor instruksjonsavsnittet,input.authcode(medid="authcode") for TOTP-koden, e-postkoden og reservekoden; feltet harinputmode="numeric"ogautocomplete="one-time-code", så ikke overstyr de attributtene med script, ellers slutter telefonen å foreslå koden fra SMS eller passordbehandleren,.backup-methods-wrapfor lenkene til alternative metoder,.two-factor-email-resendfor knappen som sender e-postkoden på nytt.
.login .two-factor-prompt {
color: #c9d1d9;
}
.login input.authcode {
letter-spacing: 0.2em;
text-align: center;
}
.login .backup-methods-wrap a {
color: #c9d1d9;
}Eldre guider bruker selektorer som .backup-methods, .two-factor-email eller .two-factor-totp. Ingen av dem finnes i dagens kode for utvidelsen, så reglene treffer aldri. Andre 2FA- og passkey-plugins har egen markup: les selektorene i koden deres, ikke i denne guiden.
Test recovery codes i staging før go-live. En merket innlogging uten fungerende 2FA-recovery er verre enn standardskjermen.
Sjekkliste for innloggingssiden før lansering
- Logo lastes over HTTPS uten blandet innhold
login_headerurlpeker til produksjonsforside (ikke staging-domene etter cutover)- Feilmelding er generisk på både norsk og engelsk locale hvis begge brukes
- Risting er slått av via
shake_error_codeshvis ønsket - Mobile: skjemaet er lesbart på 375px bredde
mu-plugins-filen er i repo og dokumentert i overleveringsnotat- 2FA / passkey flyt testet med én ikke-admin-bruker
Vanlige feil ved tilpasning av wp-login.php
- Injisere jQuery tungt på login bare for animasjoner
- Skjule «Lost your password?» uten alternativ supportkanal
- Hoste logo fra et eksternt CDN uten cache-policy
- Låse innlogging bak obscurity alene (hemmelig URL) uten rate limits
- Legge merkevare-CSS i et page builder-plugin som kunden kan deaktivere
Ødelagt logo-URL og manglende glemt passord-lenke
Byråer glemmer ofte at staging og produksjon har ulike domener. Logo-URL hardkodet til staging gir ødelagt bilde etter cutover. Løsningen er alltid tema- eller plugin-relative stier via get_stylesheet_directory_uri() eller assets i must-use-plugin med plugin_dir_url(). Et annet klassisk problem: CSS lastes globalt via wp_enqueue_scripts i stedet for login_enqueue_scripts, så frontend får login-stiler og omvendt.
Vi ser også at folk fjerner «Glemt passord»-lenken for å «se ryddigere ut». Det flytter support til e-post og Slack. Behold lenken, eller erstatt den med en tydelig supportadresse. På flerspråklige nett (bokmål/nynorsk eller nb/en) må feilmeldingen og login_headertext testes i begge locales - ellers får engelske redaktører norske strenger midt i en engelsk UI, eller motsatt.
Kontrast og tilgjengelighet på innloggingssiden
White-label er ikke unnskyldning for lav kontrast. Primærknapper må ha tilstrekkelig kontrast mot bakgrunn. Feilmeldinger skal ikke kun kommuniseres med farge. Fokustilstander på felt og knapper må være synlige for tastaturnavigasjon. Hvis du bruker mørk bakgrunn, test også systemets «prefers-color-scheme» hvis frontend er lys - mange redaktører logger inn fra samme maskin som de leser nettsiden på, og forventer ikke et helt annet kontrastregime uten varsel.
Skjermlesere får tittel fra dokumentet og fra logo-lenketeksten. Tom login_headertext eller bare «Powered by WordPress» er svakt. Bruk nettstedsnavnet. Unngå bakgrunnsvideo eller store parallaks-effekter på login - det øker lastetid og gir ingenting for oppgaven «logg inn».
Når trenger du en plugin for tilpasset WordPress-innlogging
Ren PHP-tilpasning er nok for logo, CSS, feilmeldinger og redirect. Den er ikke nok når du trenger full social login, avansert brute-force-beskyttelse med geo-regler, eller et komplett white-label-admin utover login. Da er en vedlikeholdt plugin-stack bedre enn hjemmesnekret sikkerhetskode. Regelen: merkevare på login i egen mu-plugin; sikkerhetskontroller i dedikerte, oppdaterte pakker; ingen «all-in-one» som både styler login og skriver om REST-API uten at du har lest koden.
Hvordan teste innloggingssiden etter WordPress-oppdateringer
Dokumenter i overleveringen hvilken fil som eier login-stilen, hvordan logo byttes, og hvem som godkjenner endringer. Legg en regresjonstest i release-sjekklisten: åpne /wp-login.php på staging etter hver kjerneoppdatering. WordPress endrer av og til markup rundt language switcher og consent-bokser. En CSS-selektor som var stabil i fem år kan plutselig miste treff. Sett derfor versjon på enqueued CSS og bump den bevisst når du endrer filen, slik at CDN og nettlesere ikke serverer gammel stil.
Hvordan tilpasse innlogging i WooCommerce og medlemsplugins
For kunder med egne innlogginger (medlemskap, WooCommerce my-account) skill offentlig konto-innlogging fra wp-login.php for administrasjon. Kontosidene i WooCommerce og innloggingsblokkene i kassen har annen markup enn wp-login.php, så CSS for innloggingssiden endrer ikke skjemaene på my-account. Enten beholder du standardskjemaene fra Woo, eller du laster et eget stilark på de malene. Blander du begge i style-login.css, får du døde regler og en forvirret neste utvikler.
Samme skille gjelder LearnDash, MemberPress og lignende produkter: finn først adressen kundene faktisk logger inn via, og brand den flaten. En typisk byråfeil er en finpusset wp-login.php mens kundene bare ser et modalvindu på frontend som fortsatt viser WordPress-logoen i en iframe. Test begge stier med en redaktørkonto og en kundekonto før go-live.
Hvilke sikkerhetshoder WordPress sender på wp-login.php
Før du legger til egne hoder eller metatagger på innloggingssiden, sjekk hva kjernen allerede gjør. Ifølge default-filters.php og wp-login.php:
send_frame_options_header()pålogin_init(siden 3.1.3) senderX-Frame-Options: SAMEORIGIN, og siden WordPress 6.9 legger samme funksjon tilContent-Security-Policy: frame-ancestors 'self'. Innloggingssiden kan ikke rammes inn på et fremmed domene.wp_admin_headers()pålogin_init(siden 4.9) senderReferrer-Policy: strict-origin-when-cross-origin; filteretadmin_referrer_policyendrer verdien.wp_robots_sensitive_page()(siden 5.7) leggernoindexognoarchivetil meta robots, somwp_robotsskriver ut pålogin_head.wp_strict_cross_origin_referrer()(siden 5.7) legger til en referrer-metatagg med samme policy.wp_site_iconpålogin_headskriver ut favicon fra innstillingen for nettstedsikon.
I praksis dobler en egen snutt som skriver ut meta robots noindex eller en favicon-lenke på login_head bare taggene. Ikke legg til X-XSS-Protection i det hele tatt. MDN beskriver hodet som ikke-standard og foreldet, advarer om at det kan skape XSS-sårbarheter på ellers trygge nettsteder, og anbefaler Content-Security-Policy. Hoder for hele nettstedet (HSTS, CSP) hører hjemme i server- eller CDN-konfigurasjonen, ikke i PHP på login_init, slik at de også dekker wp-admin og REST.
White-label av innlogging og wp-admin
Login er ofte førsteinntrykket, men kundene tilbringer mest tid i wp-admin. Hold fargepalett og logo i sync med admin-tilpasning (menyopprydding, egne dashbord-widgeter). Når login er mørk og admin er standard grå, føles leveransen uferdig. Dokumenter tokens (primærfarge, radius, font) ett sted og gjenbruk dem i login-CSS og admin-CSS.
Hvis du allerede har en must-use-plugin for admin-meny, legg login-hooks i samme plugin under en tydelig seksjon. Én fil å reviewe i PR er bedre enn tre spredte snutter i child theme. Husk capability: login-tilpasning trenger ingen manage_options i runtime, men deploy av mu-plugin gjør det.
Logge mislykkede innlogginger i WordPress
Logg ikke passord. Logg gjerne mislykkede innlogginger på servernivå (rate, IP, user-agent) via host eller WAF. Når en klient rapporterer «jeg kommer ikke inn», skill mellom glemt passord, 2FA-lås, IP-blokk og CSS-feil som skjuler knappen. En merket login uten synlig primærknapp på mobil er en support-felle vi har sett etter aggressive display-regler.
Hvor lang tid tar white-label av innlogging
For en standard white-label login med logo, CSS, generiske feil, shake-removal og staging-sjekk: planlegg en halv dag inkludert review og mobiltest. Legg til tid hvis WooCommerce my-account skal matches, hvis flerspråk krever egne strenger, eller hvis 2FA-plugin trenger egen styling. Billigere enn å forklare WordPress-logoen i kickoff-møtet etter lansering.
Etter lansering: ta en skjermdump av login på desktop og mobil, legg den i overleveringsmappen, og gjenta sjekken etter neste WordPress-major. Små markup-endringer i kjernen er vanlige. En kvart time med regresjon sparer timer med «hvorfor er knappen borte»-support.
Oppsummering
En tilpasset innloggingsside er liten kode med stor opplevd kvalitet.
- Merk den: logo, lenke, titteltekst
- Style den: egen CSS via
login_enqueue_scripts - Sikre den: generiske feil, 2FA for admin, rate limits
- Isoler den: must-use-plugin, ikke bare tema
- Verifiser den: staging etter oppdateringer, kontrast, flerspråk
Ikke la kunden møte standard WordPress-grensesnitt på første innlogging. Det undergraver hele leveransen. Bruk et kvarter på merkevare og et kvarter på sikkerhetslag - det er billigere enn å forklare hvorfor logoen fortsatt peker til WordPress.org tre måneder etter lansering.
Se vår WordPress-sikkerhetsrevisjon når neste steg er hardening utover skjermen.







