부트스트랩 설치하고 레이아웃 빌딩 합니다.
bootstrap install setting manual
Bootstrap?Bootstrap은 Twitter 개발자들이 만들었습니다.성능이 좋아서 현재도 지속적으로 관리되고 있는 오픈소스 프로젝트입니다. 프로젝트 진행 시 팀에 디자이너가 없는 경우에도 개발자가 괜찮
lshjju.tistory.com
위 포스팅에서 Next.js 용 설치 부분을 참고해서 설치 하세요.
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
page.tsx
클라이언트사이드렌더링 데클러레이션 합니다.
넥스트의 디폴트는 서버사이드렌더링입니다.
서버사이드렌더링 파일이 아닌 경우 이렇게 클라이언트사이드임을 선언을 해야 에러가 안 납니다.
부트스트랩 css 와 js를 임포트 합니다.
import 'bootstrap/dist/css/bootstrap.min.css';
app/layout.tsx
부트스트랩 css 추가 합니다.
function Nav() {
return (
<nav className="navbar navbar-expand-lg bg-body-tertiary m-3">
<div className="container-fluid">
<Link href="/" className="navbar-brand">
<img src="./next.svg" width="50" />
</Link>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav">
<Link href="/bros" className="nav-link">
Bros
</Link>
<Link href="/login" className="nav-link">
login
</Link>
<Link href="/detail" className="nav-link">
detail
</Link>
</div>
</div>
</div>
</nav>
);
}
원래 있던 네브/푸터 유아이를 부트스트랩으로 업그레이드 하겠습니다.
펑션루트레이아웃 아래에
위 부트스트랩 포스팅
/ Recommedation components / nav
를 참고하여 네브 컴포넌트를 코딩 합니다.
function Footer() {
return (
<div className="card m-3">
<div className="card-header">Image Copyright</div>
<div className="card-body">
<h5 className="card-title">Unsplash</h5>
<p className="card-text">
With supporting text below as a natural lead-in to additional content.
</p>
<a
href="https://unsplash.com/"
className="btn btn-outline-secondary fs-6"
>
Go unsplash
</a>
</div>
</div>
);
}
위 부트스트랩 포스팅
/ Recommedation components / footer
를 참고하여 푸터 컴포넌트를 코딩 합니다.
<body className={inter.className}>
<Nav />
{children}
<Footer />
</body>
네브/푸터 펑션 세팅 합니다.
펑션 루트레이아웃 바디 태그를 위와 같이 수정 합니다.
test
네브를 테스트 합니다.
탭했을때 각 페이지가 잘 렌더링 되는지 체크 합니다.

Completion
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
export default function Home() {
return (
<main>
<h1>Nextagram</h1>
</main>
);
}
page.tsx
import './globals.css';
import type { Metadata } from 'next';
import { Inter } from 'next/font/google';
import Link from 'next/link';
import 'bootstrap/dist/css/bootstrap.min.css';
const inter = Inter({ subsets: ['latin'] });
export const metadata: Metadata = {
title: 'Create Next App',
description: 'Generated by create next app',
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>
<Nav />
{children}
<Footer />
</body>
</html>
);
}
function Nav() {
return (
<nav className="navbar navbar-expand-lg bg-body-tertiary m-3">
<div className="container-fluid">
<Link href="/" className="navbar-brand">
<img src="./next.svg" width="50" />
</Link>
<button
className="navbar-toggler"
type="button"
data-bs-toggle="collapse"
data-bs-target="#navbarNavAltMarkup"
aria-controls="navbarNavAltMarkup"
aria-expanded="false"
aria-label="Toggle navigation"
>
<span className="navbar-toggler-icon"></span>
</button>
<div className="collapse navbar-collapse" id="navbarNavAltMarkup">
<div className="navbar-nav">
<Link href="/bros" className="nav-link">
Bros
</Link>
<Link href="/login" className="nav-link">
login
</Link>
<Link href="/detail" className="nav-link">
detail
</Link>
</div>
</div>
</div>
</nav>
);
}
function Footer() {
return (
<div className="card m-3">
<div className="card-header">Image Copyright</div>
<div className="card-body">
<h5 className="card-title">Unsplash</h5>
<p className="card-text">
With supporting text below as a natural lead-in to additional content.
</p>
<a
href="https://unsplash.com/"
className="btn btn-outline-secondary fs-6"
>
Go unsplash
</a>
</div>
</div>
);
}
layout.tsx
홈 유아이 빌딩 합니다.
import Link from 'next/link';
page.tsx
a 태그가 아닌 링크 라이브러리를 사용하여 각 페이지를 연결할 것입니다.
그러기 위해 링크 임포트 합니다.
function Post() {
return (
<div className="">
<div className="card m-3">
<img
src={`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/1.PNG`}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">elegance</h5>
<p className="card-text">
It is a long established fact that a reader will be distracted
</p>
<p className="card-text">
<small>20250228</small>
</p>
<p className="card-text">Like it 25</p>
<Link href="/detail" className="btn btn-outline-secondary">
Detail
</Link>
</div>
</div>
</div>
);
}
이제 메인에 실제 콘텐츠를 배치해 보겠습니다.
펑션홈 아래에 펑션포스트 추가 합니다.
이 유아이도 부트스트랩 디자인을 사용 합니다.
function Pagenation() {
return (
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a class="page-link">Previous</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
1
</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
2
</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
3
</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
Next
</a>
</li>
</ul>
</nav>
);
}
위 부트스트랩 포스팅
/ Recommedation components / footer
를 참고하여 펑션 포스트 아래에 펑션 페이지네이션 추가 합니다.
export default function Home() {
return (
<main>
<h1>Nextagram</h1>
<Post />
<Pagenation />
</main>
);
}
펑션을 연결 합니다.
test
부트스트랩 유아이가 잘 설치 되었는지 체크 합니다.

Completion
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
import 'bootstrap/dist/js/bootstrap.bundle.min.js';
import Link from 'next/link';
export default function Home() {
return (
<main>
<h1>Nextagram</h1>
<Post />
<Pagenation />
</main>
);
}
function Post() {
return (
<div className="">
<div className="card m-3">
<img
src={`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/1.PNG`}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">elegance</h5>
<p className="card-text">
It is a long established fact that a reader will be distracted
</p>
<p className="card-text">
<small>20250228</small>
</p>
<p className="card-text">Like it 25</p>
<Link href="/detail" className="btn btn-outline-secondary">
Detail
</Link>
</div>
</div>
</div>
);
}
function Pagenation() {
return (
<nav aria-label="Page navigation example">
<ul class="pagination justify-content-center">
<li class="page-item disabled">
<a class="page-link">Previous</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
1
</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
2
</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
3
</a>
</li>
<li class="page-item">
<a class="page-link" href="#">
Next
</a>
</li>
</ul>
</nav>
);
}
브로스 유아이 빌딩 합니다.
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
/bros/page.tsx
앞서 메인과 유사한 방식으로 브로스페이지 유아이를 설치하겠습니다.
클라이언트사이드렌더링 데클러레이션 합니다.
부트스트랩 css 임포트 합니다.
아쉽게도 부트스트랩을 각 페이지마다 설치해야 제대로 작동하는것 같습니다.
function Bro() {
return (
<ol className="list-group list-group-numbered m-3">
<li className="list-group-item d-flex justify-content-between align-items-start">
<div className="ms-2 me-auto">
<div className="fw-bold">Jane Doe</div>
<small className="text-body-tertiary">
Lorem ipsum dolor sit amet, consectetur
</small>
</div>
<span className="badge text-bg-primary rounded-pill">
<small>Unfollow</small>
</span>
</li>
</ol>
);
}
위 부트스트랩 포스팅
/ Recommedation components / list
를 참고하여 펑션브로스 아래에 펑션브로 추가 합니다.
function Pagenation() {
return (
<nav aria-label="Page navigation example">
<ul className="pagination justify-content-center m-3">
<li className="page-item disabled">
<a className="page-link">Previous</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
1
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
2
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
3
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
Next
</a>
</li>
</ul>
</nav>
);
}
위 부트스트랩 포스팅
/ Recommedation components / pagenation
참고하여 펑션브로 아래에 펑션페이지네이션 코딩 합니다.
export default function Bros() {
return (
<div>
<h4>Bros</h4>
<Bro />
<Pagenation />
</div>
);
}
펑션브로스 컴포넌트 추가 합니다.
test
유아이 체크 합니다.

Competion
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
export default function Bros() {
return (
<div>
<h4>Bros</h4>
<Bro />
<Pagenation />
</div>
);
}
function Bro() {
return (
<ol className="list-group list-group-numbered m-3">
<li className="list-group-item d-flex justify-content-between align-items-start">
<div className="ms-2 me-auto">
<div className="fw-bold">Jane Doe</div>
<small className="text-body-tertiary">
Lorem ipsum dolor sit amet, consectetur
</small>
</div>
<span className="badge text-bg-primary rounded-pill">
<small>Unfollow</small>
</span>
</li>
</ol>
);
}
function Pagenation() {
return (
<nav aria-label="Page navigation example">
<ul className="pagination justify-content-center m-3">
<li className="page-item disabled">
<a className="page-link">Previous</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
1
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
2
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
3
</a>
</li>
<li className="page-item">
<a className="page-link" href="#">
Next
</a>
</li>
</ul>
</nav>
);
}
로그인 유아이 빌딩 합니다.
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
export default function Login() {
return (
<div className="m-3">
<h4>Log in</h4>
<form>
<div className="row mb-3">
<label for="inputEmail3" className="col-sm-2 col-form-label">
Email
</label>
<div className="col-sm-10">
<input type="email" className="form-control" id="inputEmail3" />
</div>
</div>
<div className="row mb-3">
<label for="inputPassword3" className="col-sm-2 col-form-label">
Password
</label>
<div className="col-sm-10">
<input
type="password"
className="form-control"
id="inputPassword3"
/>
</div>
</div>
<div className="row mb-3">
<div className="col-sm-10 offset-sm-2">
<div className="form-check">
<input
className="form-check-input"
type="checkbox"
id="gridCheck1"
/>
<label className="form-check-label" for="gridCheck1">
Example checkbox
</label>
</div>
</div>
</div>
<button type="submit" className="btn btn-primary">
Auto login
</button>
</form>
</div>
);
}
/login/page.tsx
클라이언트사이드렌더링 데클러레이션 합니다.
부트스트랩 css 임포트 합니다.
위 부트스트랩 포스팅
/ Recommedation components / form
참고하여 펑션로그인 코딩 합니다.
test
뷰 체크 합니다.

Completion
위 코드가 완성본 입니다.
디테일 뷰 유아이 빌딩 합니다.
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
/detail/page.tsx
클라이언트사이드렌더링 데클러레이션 합니다.
부트스트랩 css 임포트 합니다.
function Details() {
return (
<div className="card m-3">
<img
src={`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/1.PNG`}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">elegance</h5>
<p className="card-text">
It is a long established fact that a reader will be distracted by the
readable content of a page when looking at its layout. The point of
using Lorem Ipsum is that it has a more-or-less normal distribution of
letters, as opposed to using 'Content here, content here', making it
look like readable English. Many desktop publishing packages and web
page editors now use Lorem Ipsum as their default model text, and a
search for 'lorem ipsum' will uncover many web sites still in their
infancy. Various versions have evolved over the years, sometimes by
accident, sometimes on purpose (injected humour and the like).
</p>
<p className="card-text">작성일: 20250228</p>
<div className="mt-2">
<button
type="button"
className="btn active"
onClick={() => {}}
data-bs-toggle="button"
aria-pressed="true"
>
❤️️
</button>
<span> 0 </span>
</div>
<p className="card-text">
<small className="text-body-secondary">
Last updated 3 mins ago
<br />
Default like: 25
</small>
</p>
</div>
</div>
);
}
위 부트스트랩 포스팅
/ Recommedation components / card-image-caps
참고하여 펑션디테일 아래에 펑션디테일스 추가 합니다.
function Comment() {
return (
<div className="m-3">
<form>
<div className="mb-3">
<label for="exampleInputEmail1" className="form-label">
Comment
</label>
<input
type="email"
className="form-control"
id="exampleInputEmail1"
aria-describedby="emailHelp"
/>
<div id="emailHelp" className="form-text">
We'll share your story
</div>
</div>
<div className="mb-3">
<label for="exampleInputPassword1" className="form-label">
Password
</label>
<input
type="password"
className="form-control"
id="exampleInputPassword1"
/>
</div>
<div className="mb-3 form-check">
<input
type="checkbox"
className="form-check-input"
id="exampleCheck1"
/>
<label className="form-check-label" for="exampleCheck1">
Check me out
</label>
</div>
<button type="submit" className="btn btn-outline-secondary">
Submit
</button>
</form>
</div>
);
}
위 부트스트랩 포스팅
/ Recommedation components / form
참고하여 펑션디테일스 아래에 펑션코멘트 추가 합니다.
export default function Detail() {
return (
<div>
<h4>Detail</h4>
<Details />
<Comment />
</div>
);
}
디테일스 코멘트 컴포넌트 추가 합니다.
Test
뷰 체크 합니다.
이상이 없다면 굿입니다.
이렇게 각 페이지 유아이 설치를 완료했습니다.
수고하셨습니다.

Completion
'use client';
import 'bootstrap/dist/css/bootstrap.min.css';
export default function Detail() {
return (
<div>
<h4>Detail</h4>
<Details />
<Comment />
</div>
);
}
function Details() {
return (
<div className="card m-3">
<img
src={`https://raw.githubusercontent.com/lshjju/cdn/refs/heads/main/girls/1.PNG`}
className="card-img-top"
alt="..."
/>
<div className="card-body">
<h5 className="card-title">elegance</h5>
<p className="card-text">
It is a long established fact that a reader will be distracted by the
readable content of a page when looking at its layout. The point of
using Lorem Ipsum is that it has a more-or-less normal distribution of
letters, as opposed to using 'Content here, content here', making it
look like readable English. Many desktop publishing packages and web
page editors now use Lorem Ipsum as their default model text, and a
search for 'lorem ipsum' will uncover many web sites still in their
infancy. Various versions have evolved over the years, sometimes by
accident, sometimes on purpose (injected humour and the like).
</p>
<p className="card-text">작성일: 20250228</p>
<div className="mt-2">
<button
type="button"
className="btn active"
onClick={() => {}}
data-bs-toggle="button"
aria-pressed="true"
>
❤️️
</button>
<span> 0 </span>
</div>
<p className="card-text">
<small className="text-body-secondary">
Last updated 3 mins ago
<br />
Default like: 25
</small>
</p>
</div>
</div>
);
}
function Comment() {
return (
<div className="m-3">
<form>
<div className="mb-3">
<label for="exampleInputEmail1" className="form-label">
Comment
</label>
<input
type="email"
className="form-control"
id="exampleInputEmail1"
aria-describedby="emailHelp"
/>
<div id="emailHelp" className="form-text">
We'll share your story
</div>
</div>
<div className="mb-3">
<label for="exampleInputPassword1" className="form-label">
Password
</label>
<input
type="password"
className="form-control"
id="exampleInputPassword1"
/>
</div>
<div className="mb-3 form-check">
<input
type="checkbox"
className="form-check-input"
id="exampleCheck1"
/>
<label className="form-check-label" for="exampleCheck1">
Check me out
</label>
</div>
<button type="submit" className="btn btn-outline-secondary">
Submit
</button>
</form>
</div>
);
}
