# Moving a static page to Nextjs
<img styles="max-width: 100%" alt="blog1_banner" src='https://hackmd.io/_uploads/BJGS92o8A.png' />
<br/><br/>
I had worked on a NextJs project, that has a landing page created in pure HTML, CSS and JS, which was used to get users to sign up in advance. After the project was released, I was requested to move that landing page to the current NextJs source and what I did was re-creating the page. Well, this blog’s purpose is to help you avoid having the same mistake as I did 🙂 Yes, you can just move your static page to NextJs with a simple configuration if your page is the same, without any added changes.
Let’s try to replicate the situation!
### 1. Preparation
#### 1a) Create a static page
Here, I have a simple one with html, css and js file. I also add 3rd party library (slickjs to handle carousel) and a simple form, to see if it still works after the page being moved to Nextjs.
```html!
<!-- index.html -->
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.5.2/css/all.min.css" integrity="sha512-SnH5WK+bZxgPHs44uWIX+LLJAJ9/2PkPKZ5QiAj6Ta86w+fsb2TkcmfRyVX3pBnMFcV7oQPJkl9QevSCWr3W6A==" crossorigin="anonymous" referrerpolicy="no-referrer" />
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.css"/>
<link rel="stylesheet" type="text/css" href="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick-theme.css"/>
<link rel="stylesheet" href="../css/style.css"/>
<title>Blog</title>
</head>
<body class="wrapper">
<div class="navbar">
<div class="left">
<a href="/"><i class="fa-brands fa-square-facebook"></i></a>
<a href="#"><i class="fa-brands fa-instagram"></i></a>
<a href="#"><i class="fa-brands fa-snapchat"></i></a>
<a href="#"><i class="fa-brands fa-flickr"></i></a>
<a href="#"><i class="fa-brands fa-x-twitter"></i></a>
<a href="#"><i class="fa-brands fa-linkedin"></i></a>
</div>
<a href="#"><i class="fa fa-search"></i></a>
</div>
<div class="container">
<div>
<h2>New Fashion</h2>
<div class="carousel_holder">
<div class="carousel">
<img alt="" src="./imgs/img1.jpg" />
<img alt="" src="./imgs/img2.jpg" />
<img alt="" src="./imgs/img3.jpg" />
</div>
</div>
<h2>Want more latest trends?</h2>
<p>Sign up to get your newsletters every week</p>
<form id="signup" onsubmit="">
<div class="input_form">
<label for="name"><b>Enter your name</b></label>
<input type="text" name="name" id="name" required />
</div>
<div class="input_form">
<label for="email"><b>Enter your email</b></label>
<input type="email" name="email" id="email" required />
</div>
<input type="submit" value="Subscribe!" class="button_submit"/>
</form>
</div>
</div>
<script src="https://cdn-script.com/ajax/libs/jquery/3.7.1/jquery.js"></script>
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/slick-carousel@1.8.1/slick/slick.min.js"></script>
<script src="../js/index.js"></script>
</body>
</html>
```
```javascript!
<!-- script.js -->
$(document).ready(function(){
$(".carousel").slick({
arrows: true,
});
$("#signup").on("submit", function( event ) {
alert( "Successfully subscribed!" );
event.preventDefault();
})
})
```
<img alt='sample' src='https://hackmd.io/_uploads/HJP0Kd2UA.png' />
#### 1b) Create Nextjs project
Simply use below command and follow guided questions to create your project. In this example, i'm using Page Router approach, but it's the same for App Router.
```json
npx create-next-app@latest
```
### 2. Moving static page to Nextjs
Before we do this, you should know that there are 2 ways to move a static page to Nextjs, which is configuring nextjs config with "redirects" option, or "rewrites" option.
We are going to try both so you can pick the one that most matches your use case. In the example, i'm assumming that we will render static page on "/" route, but in case the static page in NextJs has a different route, be sure to add a page to match that route.
#### 2a) Using "redirects"
**First,** move whole folder that contains your static page to public folder in NextJS.

**Second,** modify your `next.config.mjs` file.
```jsonld!
module.exports = {
async redirects() {
return [
{
source: '/',
destination: '/static/index.html',
permanent: true,
},
]
},
}
```
With this setup, Nextjs will check if the incoming request path pattern (source) is match. If matches, it will redirect to destination path. `permanent` property expects `true/false` value, `true` means the 308 status code which instructs clients/search engines to cache the redirect forever will be used, and `false` means the 307 status code which is temporary and is not cached will be used.
With this approach, the route after redirected will be `www.you_domain.com/static/index.html`.
#### 2b) Using "rewrites"
**First,** a bit different with "redirects", when using "rewrites", you need to separate html, css, js file in static source and modify the import link in html file before moving to public folder.

```html!
- <link rel="stylesheet" href="./style.css"/>
+ <link rel="stylesheet" href="../css/style.css"/>
...
- <script src="./index.js"></script>
+ <script src="../js/index.js"></script>
```
**Second,** modify your `next.config.mjs` file.
```jsonld!
module.exports = {
async rewrites() {
return {
beforeFiles: [
{
source: "/",
destination: "/html/index.html",
},
],
}
},
}
```
When the rewrites function returns an array, rewrites are applied after checking the filesystem (pages and /public files) and before dynamic routes to find matching source but this behaviour can be changed with these 3 options: beforeFiles, afterFiles, fallback.
- *beforeFiles*: These rewrites are checked after headers/redirects and before all files including _next/public files which allows overriding page files.
- *afterFiles*: These rewrites are checked after pages/public files are checked but before dynamic routes.
- *fallback*: These rewrites are checked after both pages/public files and dynamic routes are checked.
If you use `rewrites` like this, the option is "afterFiles" by default.
```javascript!
async rewrites() {
return [
{
// this will match `/english(default)/something` being requested
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
},
]
},
```
With this approach, the route after redirected will be the source route, but the content is your static page.
#### 2c) Result
As you can see, i have used rewrites to display the static page under `/lp` route and it works just fine.
<img alt='sample' src='https://hackmd.io/_uploads/HyVj1i6LR.png' />
### 3. What is the difference between "redirects" and "rewrites"
So what is the difference, you may ask.
The first difference is obvious, as I have already mentioned, is the url. But that's the tip of the iceberg, here are the other differences.
| # | Redirects | Rewrites |
| -------- | -------- | -------- |
| Where does this happen | Both client and server side | Server side only |
| Order of execution | Immediately change URL | Before dynamics routes |
| Status code | 307 or 308 status code | No status code |
| Debug ability | Easy | Not easy |
Rewrites act as a URL proxy and are handled entirely on the server side. They map an incoming request path to a different destination path without changing the URL in the browser. ***While,*** redirects can be handled both on the client side (using the useRouter hook) and server side (configured in next.config.js). They change the URL in the browser and send an HTTP status code. That's why the url remains the same when we use "rewrites" and changes when we use "redirects".
Rewrites are applied after checking the filesystem (pages and public files) and before dynamic routes. If there are conflicts or issues in this order, rewrites might not work as expected. ***While,*** redirects immediately change the URL in the browser, making it clear to the user that they have been redirected to a new page.
### 4. Debug and conclusion
Regarding above differeces, if your rewrites aren’t working but redirects are, it could be due to:
- File System Conflicts: Ensure there are no conflicts with existing files or routes that might be interfering with the rewrites.
- Order of Execution: Verify that the rewrites are correctly placed in the next.config.js and are being executed in the right order.
- Browser Cache: Clear your browser cache or test in an incognito window to rule out caching issues.
In general, it's pretty easy moving a static page to Nextjs as you can see. In case you need to add some routing on the static page, it's completely fine. However, if you need to add functions such as calling apis that are used within Nextjs project, it's probably not a good idea to do this. You might tweek it a bit by redirecting to a Nextjs page and call api there, but again, might not a really good idea. As always, one case deosn't fit all, it's best to consider the situation of your project and make decision.
<small>
Published date: 2024-07-08 <br/>
Also published <a href="https://josysnavi.jp/2024/blog-00032">here</a>.
</small>