Slik konverterer du statisk HTML til et WordPress-tema uten å ødelegge nettstedet
AI-verktøy kan generere et pent statisk HTML-nettsted på minutter, og det er nyttig. Men en statisk HTML-fil er ikke et WordPress-tema. En statisk side er bare markup, CSS og JavaScript. Et tema må fungere inne i et dynamisk system med maler, hooks, menyer, plugins, skjemaer, SEO-plugins, caching og noen ganger WooCommerce.
Problemene starter når et statisk design tvinges inn i WordPress med snarveier: man laster opp home.html, skriver om / til en HTML-fil, hardkoder ressurs-URL-er eller hopper over wp_head() og wp_footer(). Forsiden ser fin ut mens resten av nettstedet ryker. Denne guiden viser hvordan du gjør statisk HTML om til et ordentlig tema uten å ødelegge ruting, plugins, skjemaer, kassen, SEO eller fremtidige oppdateringer.
Statisk HTML vs WordPress-tema: kjerneforskjellen
Et statisk HTML-nettsted har som regel filer som:
home.html
about.html
contact.html
style.css
script.js
images/
Hver side er en egen fil, og lenkene peker rett på filer. Et enkelt klassisk WordPress-tema ser annerledes ut:
style.css
functions.php
header.php
footer.php
front-page.php
page.php
single.php
index.php
assets/
css/
js/
images/
template-parts/
Bare style.css og index.php er påkrevd. For hver forespørsel finner WordPress ut hva slags side som blir bedt om, og leter nedover malhierarkiet til den finner en passende fil i temaet. Temaet står for oppsettet, mens WordPress håndterer ruting, innhold, plugins og menyer. Derfor bør et statisk design konverteres inn i temasystemet, ikke tvinges rundt det.
Hvorfor du ikke bare bør laste opp HTML-filer til WordPress
Det er fristende å laste opp home.html og hente den inn med en .htaccess-regel som:
RewriteRule ^$ /home.html [L]
Forsiden laster raskt. Problemet dukker opp et annet sted. I .htaccess sammenligner Apache mønsteret bare med stien, aldri med spørrestrengen, og spørrestrengen sendes videre uendret. Derfor treffer ^$ både den rene forsiden og alle forespørsler til rota som har parametere. WooCommerce sine AJAX-endepunkter er nettopp slike: hjemmeadressen pluss ?wc-ajax=update_order_review og lignende. De får home.html tilbake i stedet for JSON. Vi har sett akkurat dette i en kassesak der en regel for statisk forside fanget opp WooCommerce-AJAX og fikk kassen til å laste i det uendelige.
Forespørsler som regelen fanger, når aldri fram til WordPress, så ingen PHP kjører for dem: ingen plugins, SEO-tagger, analyse, samtykkebanner, skjemabehandling eller WooCommerce-økt. Siden kan se riktig ut mens arkitekturen er skjør.
Klassisk tema eller blokktema?
WordPress har to typer temaer. Klassiske temaer bruker PHP-maler, systemet WordPress har brukt siden 2005. Blokktemaer, som Theme Handbook nå legger vekt på, bruker HTML-maler bygget av blokker, samler designinnstillingene i theme.json, og lar eieren redigere malene i nettstedsredigereren.
Denne guiden bygger et klassisk tema, fordi AI-generert HTML kan flyttes inn i PHP-maler nesten uendret. Et blokktema krever mer arbeid i starten, siden hver seksjon må bygges på nytt som blokker, men etterpå kan eieren endre header, footer og oppsett uten utvikler. Det trenger style.css og templates/index.html, har header og footer som maldeler i parts/, og følger det samme malhierarkiet. Bestem deg før du starter: å bytte senere betyr å bygge malene på nytt.
Når konvertering av statisk HTML gir mening
Konvertering lønner seg når du har et ferdig design (AI-generert eller ikke), vil at WordPress skal styre innholdet, trenger en gjenbrukbar header og footer, og vil at plugins og SEO-verktøy skal fungere. Målet er å beholde designet og samtidig gjøre strukturen WordPress-nativ.
Steg 1: Organiser de statiske filene først
Før du konverterer noe, rydd i kilden. En rotete mappe kan se slik ut:
home.html
contact.html
over-ons.html
privacybeleid.html
style-final-new.css
style2.css
script-copy.js
logo-new-final.png
img/
old/
backup/
Rydd den til noe forutsigbart:
source-html/
home.html
contact.html
privacy.html
terms.html
assets/
css/
js/
images/
Finn deretter ut hvilken fil som er forsiden, hvilke seksjoner som gjentas, hvor header og footer starter og slutter, hvilke CSS-, JS- og bildefiler som faktisk brukes, og hvilke sider som skal bli WordPress-sider. Ikke begynn å kode før du forstår kildestrukturen.
Steg 2: Lag en ordentlig temamappe
Lag en mappe i wp-content/themes/, for eksempel:
mytheme/
style.css
functions.php
index.php
header.php
footer.php
front-page.php
page.php
single.php
assets/
css/
js/
images/
template-parts/
Bytt ut mytheme med ditt eget navn, her og i funksjonsnavnene og handles under. Theme Handbook ber deg bruke et slikt prefiks, så navnene ikke kolliderer med WordPress-kjernen eller en plugin.
Steg 3: Legg til temaheaderen i style.css
WordPress registrerer temaet ut fra en header-kommentar øverst i style.css:
/*
Theme Name: Mitt tema
Theme URI: https://example.no/
Author: Ditt firma
Description: Egendefinert WordPress-tema konvertert fra statisk HTML.
Version: 1.0.0
Text Domain: mytheme
*/
Filen må ligge i rotmappen til temaet. Theme Name er det eneste feltet WordPress faktisk krever. Hoved-CSS-en kan godt ligge i assets/css/main.css, så lenge headeren finnes.
Steg 4: Sett opp functions.php
I functions.php legger du til temastøtte og menyer:
<?php
if (!defined('ABSPATH')) {
exit;
}
function mytheme_setup() {
add_theme_support('title-tag');
add_theme_support('post-thumbnails');
add_theme_support('custom-logo');
add_theme_support('html5', array(
'search-form',
'comment-form',
'comment-list',
'gallery',
'caption',
));
register_nav_menus(array(
'primary' => __('Primary Menu', 'mytheme'),
'footer' => __('Footer Menu', 'mytheme'),
));
}
add_action('after_setup_theme', 'mytheme_setup');
Registrer støtten på after_setup_theme; init er for sent for noen funksjoner. La 'style' og 'script' stå utenfor html5-lista, selv om mange guider fortsatt tar dem med: fra WordPress 7.0 er begge utfaset og ubrukt. Med title-tag skriver WordPress ut sidetittelen selv, så header.php skal ikke ha noen <title>.
Steg 5: Last inn CSS og JavaScript riktig
Statisk HTML laster ressurser med tagger som disse:
<link rel="stylesheet" href="style.css">
<script src="script.js"></script>
Theme Handbook sier at du aldri skal hardkode <link>-, <style>– eller <script>-tagger i et tema. Legg filene i køen (enqueue) på wp_enqueue_scripts-hooken, så styrer WordPress avhengigheter og rekkefølge sammen med pluginenes filer:
function mytheme_enqueue_assets() {
wp_enqueue_style(
'mytheme-main',
get_parent_theme_file_uri('assets/css/main.css'),
array(),
filemtime(get_parent_theme_file_path('assets/css/main.css'))
);
wp_enqueue_script(
'mytheme-main',
get_parent_theme_file_uri('assets/js/main.js'),
array(),
filemtime(get_parent_theme_file_path('assets/js/main.js')),
true
);
}
add_action('wp_enqueue_scripts', 'mytheme_enqueue_assets');
Versjonsargumentet legges på URL-en for cache busting, og filens endringstid gjør at nettleseren henter hver nye versjon. Den siste true laster skriptet rett før </body>, og fra WordPress 6.3 kan du gi en array i stedet, for eksempel array('in_footer' => true, 'strategy' => 'defer'). Trenger du jQuery, bruk kopien som følger med WordPress som avhengighet.
Steg 6: Konverter HTML-headeren til header.php
Flytt toppen av HTML-filen inn i header.php. En statisk fil kan starte slik:
<!DOCTYPE html>
<html lang="no">
<head>
<meta charset="UTF-8">
<title>Nettstedstittel</title>
<link rel="stylesheet" href="style.css">
</head>
<body>
<header>
...
</header>
I WordPress bør den bli:
<!DOCTYPE html>
<html <?php language_attributes(); ?>>
<head>
<meta charset="<?php bloginfo('charset'); ?>">
<meta name="viewport" content="width=device-width, initial-scale=1">
<?php wp_head(); ?>
</head>
<body <?php body_class(); ?>>
<?php wp_body_open(); ?>
<header class="site-header">
<div class="container">
<a class="site-logo" href="<?php echo esc_url(home_url('/')); ?>">
<?php bloginfo('name'); ?>
</a>
<?php
wp_nav_menu(array(
'theme_location' => 'primary',
'menu_class' => 'primary-menu',
'container' => 'nav',
'container_class'=> 'site-navigation',
'fallback_cb' => false,
));
?>
</div>
</header>
Fjern aldri wp_head(). WordPress bruker den til å skrive ut tittel-taggen, utløse wp_enqueue_scripts og skrive ut stilarkene og skriptene som er lagt i køen, også dine egne fra steg 5. Behold wp_body_open() også: den kjører rett etter <body>, der plugins skriver ut kode og WordPress tegner adminlinjen.
Steg 7: Konverter footeren til footer.php
Bunnen av den statiske filen går inn i footer.php:
<footer>
...
</footer>
<script src="script.js"></script>
</body>
</html>
I WordPress:
<footer class="site-footer">
<div class="container">
<p>© <?php echo esc_html(date('Y')); ?> <?php bloginfo('name'); ?>. Alle rettigheter reservert.</p>
<?php
wp_nav_menu(array(
'theme_location' => 'footer',
'menu_class' => 'footer-menu',
'container' => 'nav',
'fallback_cb' => false,
));
?>
</div>
</footer>
<?php wp_footer(); ?>
</body>
</html>
Ikke fjern wp_footer(). Den skriver ut alle skript som er lagt i køen for bunnen av siden, både dine og pluginenes. Uten den virker ikke skjemaer, analyse, cookie-bannere, slidere, mobilmenyer, live chat og sporingspiksler som laster der. En manglende wp_footer() er en vanlig grunn til at nettsteder ryker etter HTML-konvertering.
Steg 8: Konverter forsiden til front-page.php
Når front-page.php finnes, bruker WordPress den alltid som forside, uansett hva som står under Innstillinger → Lesing. Derfor er det den riktige malen for en egendefinert forside:
<?php get_header(); ?>
<main id="main" class="site-main">
<section class="hero">
<div class="container">
<h1>Din viktigste overskrift</h1>
<p>Én tydelig setning om hva du tilbyr.</p>
</div>
</section>
<section class="services">
...
</section>
</main>
<?php get_footer(); ?>
Innholdet ligger mellom get_header() og get_footer(). Lim aldri inn et nytt, fullstendig HTML-dokument i malen:
<?php get_header(); ?>
<!DOCTYPE html>
<html>
<head>
...
</head>
<body>
...
</body>
</html>
<?php get_footer(); ?>
Det dupliserer dokumentstrukturen og gir problemer med oppsett, SEO og skript.
Steg 9: Konverter undersider til WordPress-sider
Sider som about.html, contact.html og privacy.html trenger sjelden egne PHP-maler. Opprett vanlige sider i admin, lim inn det rensede innholdet, og la page.php stå for oppsettet:
<?php get_header(); ?>
<main id="main" class="site-main">
<div class="container">
<?php
while (have_posts()) :
the_post();
?>
<article id="post-<?php the_ID(); ?>" <?php post_class(); ?>>
<h1><?php the_title(); ?></h1>
<div class="entry-content">
<?php the_content(); ?>
</div>
</article>
<?php
endwhile;
?>
</div>
</main>
<?php get_footer(); ?>
Bruk egendefinerte sidemaler bare når en side trenger en helt egen struktur.
Steg 10: Fiks bilde- og ressursstier
Statisk HTML bruker ofte relative stier:
<img src="images/hero.png" alt="Hero-bilde">
Inne i et tema, bruk:
<img src="<?php echo esc_url(get_parent_theme_file_uri('assets/images/hero.png')); ?>" alt="Hero-bilde">
WordPress-adresser som /om-oss/ er ikke mapper på disken, så en relativ sti får nettleseren til å be om /om-oss/images/hero.png og få 404. Absolutte stier ryker når nettstedet flyttes fra staging til produksjon eller til et nytt domene. Bruk hjelpefunksjonene fra Theme Handbook for alle ressurs-URL-er (get_theme_file_uri() hvis et barnetema skal kunne bytte ut filen), og legg innholdsbilder i mediebiblioteket.
Steg 11: Erstatt statiske menyer med WordPress-menyer
En statisk meny:
<nav>
<a href="/">Hjem</a>
<a href="/about.html">Om oss</a>
<a href="/contact.html">Kontakt</a>
</nav>
blir en WordPress-meny:
wp_nav_menu(array(
'theme_location' => 'primary',
'menu_class' => 'primary-menu',
'container' => 'nav',
'container_class'=> 'site-navigation',
'fallback_cb' => false,
));
Lag deretter menyen og knytt den til plasseringen Primary under Utseende → Menyer. Den skjermen gjelder klassiske temaer; blokktemaer bygger menyer med Navigasjon-blokken i nettstedsredigereren (Utseende → Redigeringsverktøy). 'fallback_cb' => false hindrer WordPress i å liste opp alle sidene så lenge ingen meny er valgt.
Steg 12: Hold skjemaer WordPress-native
Statiske kontaktskjemaer ser ofte slik ut:
<form action="mailto:[email protected]">
...
</form>
Et mailto:-skjema når aldri nettstedet ditt, så ingenting blir validert, lagret eller logget. Bruk Contact Form 7, Fluent Forms, WPForms, Gravity Forms eller en egen håndterer som ligger i en plugin, fordi Theme Handbook sier at viktig funksjonalitet hører hjemme i plugins, så den overlever et temabytte. En håndterer må validere og sanitere inndata, escape utdata, sjekke en nonce, stoppe spam og få e-posten levert. Det er i leveringen mange skjemaproblemer oppstår (se hvorfor kontaktskjemaet ikke sender e-post).
Steg 13: Bevar SEO og plugin-output
Statisk HTML hardkoder metatagger:
<title>Sidetittel</title>
<meta name="description" content="...">
I WordPress skriver SEO-plugins selv ut tittel, metabeskrivelse, kanonisk URL, Open Graph-tagger, schema og robots-tagger, gjennom wp_head(). Lar du en hardkodet <title> stå samtidig som temaet har title-tag-støtte, får hver side to titler. Fjerner du wp_head(), forsvinner plugin-outputen helt. Sjekk også brødsmuler, sitemap, analyse, cookie-samtykke og strukturerte data. Et tema kan se riktig ut og likevel være teknisk svakt.
Steg 14: Hold WooCommerce native når det er relevant
Gjør aldri handlekurven og kassen om til statisk HTML. WooCommerce fungerer ikke uten sidene for handlekurv, kasse og konto, og fra WooCommerce 8.3 får nye butikker Cart- og Checkout-blokkene som standard. De ligger i sideinnholdet, så page.php må kalle the_content().
På et klassisk tema erklærer du støtte med add_theme_support('woocommerce') på after_setup_theme, styler med CSS og bruker WooCommerce sine hooks til små endringer. Overstyr en mal bare når selve HTML-en må endres: overstyringer ligger i en woocommerce/-mappe i temaet, må oppdateres når WooCommerce endrer originalen, og må beholde alle hooks, ellers kan ikke plugins legge til innholdet sitt. Test deretter hele ordreflyten.
Steg 15: Unngå dupliserte headere, footere og sidebars
En vanlig overraskelse etter aktivering er en spalte ingen har bedt om: en søkeboks, siste innlegg, arkiver, kategorier. Som regel betyr det at feil mal lastes, eller at sidebar-kode har fulgt med fra et starttema. Søk i temafilene etter:
get_sidebar();
dynamic_sidebar();
the_widget();
Fjern kallene du ikke trenger. For å se hvilken mal som faktisk lastes, legg en midlertidig kommentar øverst i front-page.php på staging, last forsiden på nytt og se på kildekoden:
<!-- mal: front-page.php -->
Mangler kommentaren, bruker WordPress en annen mal.
Steg 16: Gjør temaet mobiltilpasset
Konvertering kan ødelegge et responsivt design. Sjekk mobilheaderen, menyknappen, hero-seksjonen, skjemaer, tabeller, kassen, footerkolonner og lange overskrifter. Enhetsmodus i DevTools hjelper, men avslutt testingen på ekte telefoner. Følg spesielt med på:
max-width
overflow-x
grid-template-columns
flex-wrap
position: fixed
sticky headers
De fleste statiske design har en grunnmur som dette. Legg den til hvis ditt mangler den:
* {
box-sizing: border-box;
}
img {
max-width: 100%;
height: auto;
}
Horisontal scrolling på mobil betyr som regel at ett element er bredere enn skjermen. Gi midlertidig alle elementer en ramme med * { outline: 1px solid red; }, finn boksen som stikker ut, og fiks det elementet i stedet for å skjule overflyten på hele siden.
Steg 17: Test WordPress-malhierarkiet
Malene som betyr mest for et konvertert nettsted:
front-page.php → forside
page.php → vanlige sider
single.php → blogginnlegg
singular.php → innlegg og sider uten egen mal
archive.php → arkiver
404.php → ikke funnet-side
index.php → reserve for alt
WordPress krever bare index.php, ved siden av style.css. Ta med minst front-page.php, page.php, single.php og index.php, pluss 404.php så sider som ikke finnes, beholder designet ditt. En svært enkel index.php:
<?php get_header(); ?>
<main id="main" class="site-main">
<div class="container">
<?php
if (have_posts()) :
while (have_posts()) :
the_post();
the_title('<h2>', '</h2>');
the_excerpt();
endwhile;
else :
echo '<p>Fant ikke noe innhold.</p>';
endif;
?>
</div>
</main>
<?php get_footer(); ?>
Alle forespørsler WordPress ikke finner en bedre mal for, havner i index.php, så ikke stol på front-page.php alene.
Steg 18: Test etter aktivering
Test forsiden, vanlige sider, et blogginnlegg, 404-siden, søk, kontaktskjemaet, menyer på desktop og mobil, footerlenker, adminlinjen, SEO-output, cookie-banneret, analyse og caching. Med WooCommerce tester du også produktsiden, handlekurven, kassen, betalingsmetodene, ordrebekreftelsen og e-postene. Et tema er klart når hele nettstedet fungerer, ikke når forsiden ser riktig ut.
Vanlige feil under konvertering
- Hardkodede lokale stier som
C:/Users/Desktop/site/style.css: last inn medwp_enqueue_style(). - Manglende
wp_head()ellerwp_footer(): din egen CSS og JS, plugin-skript og SEO-output ryker. - Fullstendige HTML-dokumenter i malene: ingen ekstra
html,headellerbodynår du brukerget_header()ogget_footer(). - Forsiden servert gjennom .htaccess: bruk
front-page.php. - Hardkodede menyer: bruk
wp_nav_menu(). - Redigering på live uten backup: ha alltid en vei tilbake.
En tryggere arbeidsflyt for konvertering
- Ta backup av nettstedet og lag en staging-kopi.
- Organiser de statiske HTML-filene.
- Velg klassisk tema eller blokktema.
- Lag temamappen med
style.cssogfunctions.php. - Last inn CSS og JS riktig.
- Bygg
header.phpogfooter.php. - Konverter forsiden til
front-page.php. - Lag
page.php,single.phpogindex.php. - Erstatt hardkodede stier og menyer.
- Koble skjemaene til et ekte skjemasystem.
- Test plugin-output, mobil og forretningskritiske flyter.
- Publiser, tøm all cache og test på nytt.
Dette tar lengre tid enn å laste opp en HTML-fil, men det er tryggere og langt enklere å vedlikeholde.
Når du bør be om hjelp
Få hjelp hvis forsiden fungerer men andre sider ryker, uventede widgeter dukker opp, CSS ikke laster, plugins eller skjemaer slutter å virke, menyene ikke kan redigeres, SEO-tagger mangler, feil mal lastes, eller .html-filer og .htaccess-regler holder nettstedet sammen. Henger kassen, har vi en egen guide: WooCommerce checkout henger i innlasting. Deler WordPress nettstedet med en eldre egenutviklet PHP-applikasjon, les rekkefølgen vi jobber i når WordPress står ved siden av en gammel PHP-applikasjon. Slike tegn betyr som regel at strukturen trenger opprydding, ikke flere lapper.
Avsluttende tanker
Å døpe om .html-filer til .php gir ikke et WordPress-tema. En ordentlig konvertering flytter designet inn i WordPress: header i header.php, footer i footer.php, forside i front-page.php, filer lastet inn riktig, menyer og skjemaer styrt av WordPress, og rutingen overlatt til WordPress. AI-generert HTML er et fint utgangspunkt, men det ferdige nettstedet trenger fortsatt den strukturen.
Har du et ferdig design som skal bli en ordentlig WordPress-nettside? Da bygger vi det som et ekte tema: lage WordPress-nettside starter på 9 990 kr eks. mva., og du får et skriftlig tilbud med fast pris før vi starter. Blander nettstedet ditt allerede statisk HTML, egen PHP og WordPress-maler, rydder vi opp i strukturen med WordPress-hjelp til 990 kr/t eks. mva. Send oss nettstedet, så staker vi ut den tryggeste veien til et ordentlig tema.
Kilder
Sist kontrollert 12. november 2026.
- WordPress Theme Handbook: What Is a Theme?. Blokktemaer og klassiske temaer, og hvorfor viktig funksjonalitet hører hjemme i plugins.
- WordPress Theme Handbook: Theme Structure. Filene et blokktema trenger.
- WordPress Theme Handbook: Main Stylesheet (style.css). Plassering og påkrevd headerfelt.
- WordPress Theme Handbook: Template Files. Påkrevde filer og front-page.php.
- WordPress Theme Handbook: Template Hierarchy. Hvordan WordPress velger mal.
- WordPress Theme Handbook: Theme Functions. Oppsettfunksjon, prefikser og menyer.
- WordPress Theme Handbook: Including Assets. Innlasting, versjoner, lastestrategier og URL-funksjoner.
- WordPress Theme Handbook: Navigation Menus. Menyskjermen og fallback_cb.
- WordPress Developer Reference: add_theme_support(). title-tag og de utfasede html5-argumentene.
- WordPress Developer Reference: wp_enqueue_script(). Avhengigheten av wp_head() og wp_footer().
- WordPress-kjernen på GitHub: default-filters.php. Hva wp_head(), wp_body_open() og wp_footer() skriver ut.
- WordPress Developer Resources: Security. Validering, sanitering og escaping av skjemadata.
- WooCommerce Developer Docs: Classic theme developer handbook. Temastøtte, hooks og overstyringer.
- WooCommerce: Page shortcodes. Påkrevde butikksider og blokkene som standard fra 8.3.
- Apache HTTP Server Documentation: mod_rewrite. Mønsteret matcher stien, ikke spørrestrengen.
- WooCommerce på GitHub: class-wc-ajax.php. Formatet på ?wc-ajax=-endepunktene.
Relaterte artikler
Hvordan AI-genererte .htaccess-regler kan ødelegge WordPress
En enkelt AI-generert .htaccess-regel kan endre hvordan hver forespørsel når WordPress, og ødelegge kassen, AJAX, skjemaer eller REST API mens forsiden fortsatt laster helt fint. Her er hvorfor slike regler er så risikable, feilene du bør unngå, og hvordan du går gjennom en regel trygt før den går live.
Les artikkelenFør du limer AI-generert PHP inn i WordPress, sjekk disse tingene
AI kan skrive en PHP-kodesnutt for WordPress på sekunder, men limt inn uten gjennomgang kan den utløse advarsler, bryte AJAX-kallene i kassen, gi hvit skjerm eller skape omdirigeringsløkker. Her er de 14 tingene du bør sjekke før du limer AI-generert PHP inn i WordPress, fra variabelsjekker og sanitering til hooks, nonces og en tryggere plassering, med før-og-etter-kode.
Les artikkelenSjekkliste for gjennomgang av AI-generert WordPress-kode
AI kan generere WordPress-kode på sekunder, men en kodesnutt som ser riktig ut, kan likevel bryte kassen, omdirigeringer, AJAX eller plugin-kompatibilitet. Denne sjekklisten i 20 punkter gir deg en praktisk måte å gå gjennom AI-generert kode på før den berører functions.php, .htaccess eller WooCommerce, og dekker plassering, hooks, sanitering, escaping, sikkerhet, ytelse og en plan for tilbakerulling.
Les artikkelen