1.
Initialize project
mkdir html2nextjs && cd html2nextjs
npm init -y
npm i -s react react-dom next
2. Create static directory and other assets dir
NextJs has it’s built-in handler for serving static file. If a file is located at static directory, then it
can be loaded from web page without configuring custom server or proxy
mkdir -p static/assets/template
Download Colorlib Fantom template and extract it into static/assets/template
Html to NextJs directory structure
3. Create pages and components directory
NextJs serve main pages by components inside pages directory. This directory will become
crowded when your project size grow up. Each page should only care about it’s main content; any
shared partials should be separated and storaged in other directory. We will locate them
in components . You may concern what partials are? They will be some thing
as layout , sidebar , header , footer …
mkdir pages components
4. Prepare layout file
Create file components/layout.jsx with this content
import React from 'react'
export default class AppLayout {
render() {
}
}
every thing that belong to layout should be returned from render method
Open static/assets/template/fantom/index.html in your favorite editor
A D V E R T I S E M E N T
Html to layout component
In above image, the full template was collapsed in order to keep the readability of the layout. The
html code inside red border rectangle is the only part that changed between pages, the other code
(outside the red rectangle) is the page layout.
create file components/header.jsx with content
import React from 'react'
export default class AppHeader extends React.Component {
render() {
return (
<header className="header_area">
<div className="logo_part">
<div className="container">
<a className="logo" href="#"><img
src="/static/assets/template/fantom/img/logo.png" alt="" /></a>
</div>
</div>
<div className="main_menu">
<nav className="navbar navbar-expand-lg navbar-light">
<div className="container">
{/* <!-- Brand and toggle get grouped for better mobile display -->
*/}
<a className="navbar-brand logo_h" href="index.html"><img
src="/static/assets/template/fantom/img/logo.png" alt="" /></a>
<button className="navbar-toggler" type="button" data-
toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent"
aria-expanded="false" aria-label="Toggle navigation">
<span className="icon-bar"></span>
<span className="icon-bar"></span>
<span className="icon-bar"></span>
</button>
{/* <!-- Collect the nav links, forms, and other content for
toggling --> */}
<div className="collapse navbar-collapse offset"
id="navbarSupportedContent">
<ul className="nav navbar-nav menu_nav">
<li className="nav-item active"><a className="nav-link"
href="index.html">Home</a></li>
<li className="nav-item"><a className="nav-link"
href="category.html">Category</a></li>
<li className="nav-item"><a className="nav-link"
href="archive.html">Archive</a></li>
<li className="nav-item submenu dropdown">
<a href="#" className="nav-link dropdown-toggle" data-
toggle="dropdown" role="button" aria-haspopup="true" aria-expanded="false">Pages</a>
<ul className="dropdown-menu">
<li className="nav-item"><a className="nav-link"
href="single-blog.html">Blog Details</a></li>
<li className="nav-item"><a className="nav-link"
href="elements.html">Elements</a></li>
</ul>
</li>
<li className="nav-item"><a className="nav-link"
href="contact.html">Contact</a></li>
</ul>
<ul className="nav navbar-nav navbar-right ml-auto">
<li className="nav-item"><a href="#" className="search"><i
className="lnr lnr-magnifier"></i></a></li>
</ul>
</div>
</div>
</nav>
</div>
</header>
)
}
}
create file components/footer.jsx with this content
import React from 'react'
export default class AppFooter extends React.Component {
render() {
return (
<footer className="footer-area">
<div className="container">
<div className="row">
<div className="col-lg-3 col-md-6 col-sm-6">
<div className="single-footer-widget">
<h6 className="footer_title">About Us</h6>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed
do eiusmod tempor incididunt ut labore dolore magna aliqua.</p>
</div>
</div>
<div className="col-lg-4 col-md-6 col-sm-6">
<div className="single-footer-widget">
<h6 className="footer_title">Newsletter</h6>
<p>Stay updated with our latest trends</p>
<div id="mc_embed_signup">
<form target="_blank" action="https://spondonit.us12.list-
manage.com/subscribe/post?u=1462626880ade1ac87bd9c93a&id=92a4423d01" method="get"
className="subscribe_form relative">
<div className="input-group d-flex flex-row">
<input name="EMAIL" placeholder="Email Address"
required="" type="email" />
<button className="btn sub-btn"><span className="lnr
lnr-arrow-right"></span></button>
</div>
<div className="mt-10 info"></div>
</form>
</div>
</div>
</div>
<div className="col-lg-3 col-md-6 col-sm-6">
<div className="single-footer-widget instafeed">
<h6 className="footer_title">Instagram Feed</h6>
<ul className="list instafeed d-flex flex-wrap">
<li><img
src="/static/assets/template/fantom/img/instagram/Image-01.jpg" alt="" /></li>
<li><img
src="/static/assets/template/fantom/img/instagram/Image-02.jpg" alt="" /></li>
<li><img
src="/static/assets/template/fantom/img/instagram/Image-03.jpg" alt="" /></li>
<li><img
src="/static/assets/template/fantom/img/instagram/Image-04.jpg" alt="" /></li>
<li><img
src="/static/assets/template/fantom/img/instagram/Image-05.jpg" alt="" /></li>
<li><img
src="/static/assets/template/fantom/img/instagram/Image-06.jpg" alt="" /></li>
<li><img
src="/static/assets/template/fantom/img/instagram/Image-07.jpg" alt="" /></li>
<li><img
src="/static/assets/template/fantom/img/instagram/Image-08.jpg" alt="" /></li>
</ul>
</div>
</div>
<div className="col-lg-2 col-md-6 col-sm-6">
<div className="single-footer-widget f_social_wd">
<h6 className="footer_title">Follow Us</h6>
<p>Let us be social</p>
<div className="f_social">
<a href="#"><i className="fa fa-facebook"></i></a>
<a href="#"><i className="fa fa-twitter"></i></a>
<a href="#"><i className="fa fa-dribbble"></i></a>
<a href="#"><i className="fa fa-behance"></i></a>
</div>
</div>
</div>
</div>
<div className="row footer-bottom d-flex justify-content-between align-
items-center">
<p className="col-lg-12 footer-text text-center"
suppressHydrationWarning={true}>
{/* <!-- Link back to Colorlib can't be removed. Template is
licensed under CC BY 3.0. --> */}
Copyright ©<script>document.write(new Date().getFullYear());
</script>
All rights reserved | This template is made with
<i className="fa fa-heart-o" aria-hidden="true"></i> by
<a href="https://colorlib.com" target="_blank">Colorlib</a>
{/* <!-- Link back to Colorlib can't be removed. Template is
licensed under CC BY 3.0. --> */}
</p>
</div>
</div>
</footer>
)
}
}
update file /components/layout.jsx to this
import React from 'react'
import Header from './header'
import Footer from './footer'
export default class AppLayout extends React.Component {
render() {
return (
<>
<Header />
{this.props.children}
<Footer />
</>
)
}
}
create file pages/_document.jsx with this content
import Document, { Head, Main, NextScript } from 'next/document'
export default class MyDocument extends Document {
static async getInitialProps(ctx) {
const initialProps = await Document.getInitialProps(ctx);
let props = { ...initialProps };
return props;
}
render() {
return (
<html>
<Head>
<link rel="stylesheet"
href="/static/assets/template/fantom/css/bootstrap.css" />
<link rel="stylesheet"
href="/static/assets/template/fantom/vendors/linericon/style.css" />
<link rel="stylesheet" href="/static/assets/template/fantom/css/font-
awesome.min.css" />
<link rel="stylesheet" href="/static/assets/template/fantom/vendors/owl-
carousel/owl.carousel.min.css" />
<link rel="stylesheet"
href="/static/assets/template/fantom/vendors/lightbox/simpleLightbox.css" />
<link rel="stylesheet" href="/static/assets/template/fantom/vendors/nice-
select/css/nice-select.css" />
<link rel="stylesheet" href="/static/assets/template/fantom/vendors/animate-
css/animate.css" />
<link rel="stylesheet" href="/static/assets/template/fantom/vendors/jquery-
ui/jquery-ui.css" />
{/* <!-- main css --> */}
<link rel="stylesheet" href="/static/assets/template/fantom/css/style.css"
/>
<link rel="stylesheet"
href="/static/assets/template/fantom/css/responsive.css" />
</Head>
<body>
<Main />
<NextScript />
<style dangerouslySetInnerHTML={{__html: `.owl-carousel {display:
block;}.post_slider_inner.owl-carousel > .item {
display: inline-block;
width: 25%;
}`}}></style>
</body>
</html>
);
}
}
create file pages/index.jsx that return the content part
import React from 'react'
import Layout from '../components/layout'
export default class IndexPage extends React.Component {
render() {
return (
<Layout>
{/* <!--================Post Slider Area =================--> */}
<section className="post_slider_area">
<div className="post_slider_inner owl-carousel">
<div className="item">
<div className="post_s_item">
<div className="post_img">
<img src="/static/assets/template/fantom/img/post-
slider/post-s-1.jpg" alt="" />
</div>
<div className="post_text">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd Gen Smoke +
CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar" aria-
hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o" aria-
hidden="true"></i> 05</a>
</div>
</div>
</div>
</div>
<div className="item">
<div className="post_s_item">
<div className="post_img">
<img src="/static/assets/template/fantom/img/post-
slider/post-s-2.jpg" alt="" />
</div>
<div className="post_text">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd Gen Smoke +
CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar" aria-
hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o" aria-
hidden="true"></i> 05</a>
</div>
</div>
</div>
</div>
<div className="item">
<div className="post_s_item">
<div className="post_img">
<img src="/static/assets/template/fantom/img/post-
slider/post-s-3.jpg" alt="" />
</div>
<div className="post_text">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd Gen Smoke +
CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar" aria-
hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o" aria-
hidden="true"></i> 05</a>
</div>
</div>
</div>
</div>
<div className="item">
<div className="post_s_item">
<div className="post_img">
<img src="/static/assets/template/fantom/img/post-
slider/post-s-4.jpg" alt="" />
</div>
<div className="post_text">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd Gen Smoke +
CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit,
sed do eiusmod tempor incididunt ut labore.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar" aria-
hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o" aria-
hidden="true"></i> 05</a>
</div>
</div>
</div>
</div>
</div>
</section>
{/* <!--================Blog Area =================--> */}
<section className="blog_area p_120">
<div className="container">
<div className="row">
<div className="col-lg-8">
<div className="blog_left_sidebar">
<article className="blog_style1">
<div className="blog_img">
<img className="img-fluid"
src="/static/assets/template/fantom/img/home-blog/blog-1.jpg" alt="" />
</div>
<div className="blog_text">
<div className="blog_text_inner">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd
Gen Smoke CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar"
aria-hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o"
aria-hidden="true"></i> 05</a>
</div>
</div>
</div>
</article>
<article className="blog_style1">
<div className="blog_img">
<img className="img-fluid"
src="/static/assets/template/fantom/img/home-blog/blog-2.jpg" alt="" />
</div>
<div className="blog_text">
<div className="blog_text_inner">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd
Gen Smoke CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar"
aria-hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o"
aria-hidden="true"></i> 05</a>
</div>
</div>
</div>
</article>
<div className="row">
<div className="col-md-6">
<article className="blog_style1 small">
<div className="blog_img">
<img className="img-fluid"
src="/static/assets/template/fantom/img/home-blog/blog-small-1.jpg" alt="" />
</div>
<div className="blog_text">
<div className="blog_text_inner">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>2nd Gen
Smoke Co Bomb Alarm integration</h4></a>
<p>Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore.</p>
<div className="date">
<a href="#"><i className="fa fa-
calendar" aria-hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-
comments-o" aria-hidden="true"></i> 05</a>
</div>
</div>
</div>
</article>
</div>
<div className="col-md-6">
<article className="blog_style1 small">
<div className="blog_img">
<img className="img-fluid"
src="/static/assets/template/fantom/img/home-blog/blog-small-2.jpg" alt="" />
</div>
<div className="blog_text">
<div className="blog_text_inner">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>2nd Gen
Smoke Co Bomb Alarm integration</h4></a>
<p>Lorem ipsum dolor sit amet,
consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore.</p>
<div className="date">
<a href="#"><i className="fa fa-
calendar" aria-hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-
comments-o" aria-hidden="true"></i> 05</a>
</div>
</div>
</div>
</article>
</div>
</div>
<article className="blog_style1">
<div className="blog_img">
<img className="img-fluid"
src="/static/assets/template/fantom/img/home-blog/blog-3.jpg" alt="" />
</div>
<div className="blog_text">
<div className="blog_text_inner">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd
Gen Smoke CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar"
aria-hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o"
aria-hidden="true"></i> 05</a>
</div>
</div>
</div>
</article>
<article className="blog_style1">
<div className="blog_img">
<img className="img-fluid"
src="/static/assets/template/fantom/img/home-blog/blog-4.jpg" alt="" />
</div>
<div className="blog_text">
<div className="blog_text_inner">
<a className="cat" href="#">Gadgets</a>
<a href="single-blog.html"><h4>Nest Protect: 2nd
Gen Smoke CO Alarm</h4></a>
<p>Lorem ipsum dolor sit amet, consectetur
adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad
minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip.</p>
<div className="date">
<a href="#"><i className="fa fa-calendar"
aria-hidden="true"></i> March 14, 2018</a>
<a href="#"><i className="fa fa-comments-o"
aria-hidden="true"></i> 05</a>
</div>
</div>
</div>
</article>
<nav className="blog-pagination justify-content-center d-
flex">
<ul className="pagination">
<li className="page-item">
<a href="#" className="page-link" aria-
label="Previous">
<span aria-hidden="true">
<span className="lnr lnr-chevron-left">
</span>
</span>
</a>
</li>
<li className="page-item"><a href="#"
className="page-link">01</a></li>
<li className="page-item active"><a href="#"
className="page-link">02</a></li>
<li className="page-item"><a href="#"
className="page-link">03</a></li>
<li className="page-item"><a href="#"
className="page-link">04</a></li>
<li className="page-item"><a href="#"
className="page-link">09</a></li>
<li className="page-item">
<a href="#" className="page-link" aria-
label="Next">
<span aria-hidden="true">
<span className="lnr lnr-chevron-right">
</span>
</span>
</a>
</li>
</ul>
</nav>
</div>
</div>
<div className="col-lg-4">
<div className="blog_right_sidebar">
<aside className="single_sidebar_widget search_widget">
<div className="input-group">
<input type="text" className="form-control"
placeholder="Search Posts" />
<span className="input-group-btn">
<button className="btn btn-default"
type="button"><i className="lnr lnr-magnifier"></i></button>
</span>
</div>
{/* <!-- /input-group --> */}
<div className="br"></div>
</aside>
<aside className="single_sidebar_widget author_widget">
<img className="author_img rounded-circle"
src="/static/assets/template/fantom/img/blog/author.png" alt="" />
<h4>Charlie Barber</h4>
<p>Senior blog writer</p>
<div className="social_icon">
<a href="#"><i className="fa fa-facebook"></i></a>
<a href="#"><i className="fa fa-twitter"></i></a>
<a href="#"><i className="fa fa-github"></i></a>
<a href="#"><i className="fa fa-behance"></i></a>
</div>
<p>Boot camps have its supporters andit sdetractors.
Some people do not understand why you should have to spend money on boot camp when you can get.
Boot camps have itssuppor ters andits detractors.</p>
<div className="br"></div>
</aside>
<aside className="single_sidebar_widget
popular_post_widget">
<h3 className="widget_title">Popular Posts</h3>
<div className="media post_item">
<img
src="/static/assets/template/fantom/img/blog/popular-post/post1.jpg" alt="post" />
<div className="media-body">
<a href="blog-details.html"><h3>Space The Final
Frontier</h3></a>
<p>02 Hours ago</p>
</div>
</div>
<div className="media post_item">
<img
src="/static/assets/template/fantom/img/blog/popular-post/post2.jpg" alt="post" />
<div className="media-body">
<a href="blog-details.html"><h3>The Amazing
Hubble</h3></a>
<p>02 Hours ago</p>
</div>
</div>
<div className="media post_item">
<img
src="/static/assets/template/fantom/img/blog/popular-post/post3.jpg" alt="post" />
<div className="media-body">
<a href="blog-details.html"><h3>Astronomy Or
Astrology</h3></a>
<p>03 Hours ago</p>
</div>
</div>
<div className="media post_item">
<img
src="/static/assets/template/fantom/img/blog/popular-post/post4.jpg" alt="post" />
<div className="media-body">
<a href="blog-details.html"><h3>Asteroids
telescope</h3></a>
<p>01 Hours ago</p>
</div>
</div>
<div className="br"></div>
</aside>
<aside className="single_sidebar_widget">
<a href="#"><img className="img-fluid"
src="/static/assets/template/fantom/img/blog/add.jpg" alt="" /></a>
<div className="br"></div>
</aside>
<aside className="single_sidebar_widget
post_category_widget">
<h4 className="widget_title">Post Catgories</h4>
<ul className="list cat-list">
<li>
<a href="#" className="d-flex justify-content-
between">
<p>Technology</p>
<p>37</p>
</a>
</li>
<li>
<a href="#" className="d-flex justify-content-
between">
<p>Lifestyle</p>
<p>24</p>
</a>
</li>
<li>
<a href="#" className="d-flex justify-content-
between">
<p>Fashion</p>
<p>59</p>
</a>
</li>
<li>
<a href="#" className="d-flex justify-content-
between">
<p>Art</p>
<p>29</p>
</a>
</li>
<li>
<a href="#" className="d-flex justify-content-
between">
<p>Food</p>
<p>15</p>
</a>
</li>
<li>
<a href="#" className="d-flex justify-content-
between">
<p>Architecture</p>
<p>09</p>
</a>
</li>
<li>
<a href="#" className="d-flex justify-content-
between">
<p>Adventure</p>
<p>44</p>
</a>
</li>
</ul>
<div className="br"></div>
</aside>
<aside className="single-sidebar-widget tag_cloud_widget">
<h4 className="widget_title">Tag Clouds</h4>
<ul className="list">
<li><a href="#">Technology</a></li>
<li><a href="#">Fashion</a></li>
<li><a href="#">Architecture</a></li>
<li><a href="#">Fashion</a></li>
<li><a href="#">Food</a></li>
<li><a href="#">Technology</a></li>
<li><a href="#">Lifestyle</a></li>
<li><a href="#">Art</a></li>
<li><a href="#">Adventure</a></li>
<li><a href="#">Food</a></li>
<li><a href="#">Lifestyle</a></li>
<li><a href="#">Adventure</a></li>
</ul>
</aside>
</div>
</div>
</div>
</div>
</section>
</Layout>
)
}
}
Some important notes:
You must replace all href and src value to the right assets path. For example, an image
element <img src="img/post-slider/post-s-1.jpg" alt="" /> should be changed
to <img src="/static/assets/template/fantom/img/post-slider/post-s-1.jpg"
alt="" />
Replace all class attribute to className so React can render correctly
In Footer.jsx , i added suppressHydrationWarning={true} to Copy right tag .
Inside this tag, we have document.write(new Date().getFullYear()); , when server
rendering, it will response as an empty text. But at client side, it print the current year. This
difference is normal but the goal of React SSR is to bring SSR and CSR more closer, so if
these values is difference, React will show the warning
Look at _document.jsx , this file is used for overriding default NextJs document markup.
In this file, i kept all css file but remove all js files. Css is not effect to the dom but JS does. If
we keep js files here, they may cause our dom to render incorrectly. While working in real-life
projects, you should consider to replace the use of these js files by using React component. In
this example, to keep thing simply, i choose to remove all js files; it cause the Owl
slider stop working, so i putted some css code to make the slide appear