Next js simple blog
Andi Ismail
Posted on November 8, 2022
Membuat blog sederhana
https://picsum.photos/
https://jsonplaceholder.typicode.com/
https://nextjs.org/docs/api-reference/next/image#remote-patterns
import styles from "../styles/Home.module.css"
import Image from "next/image"
import Link from "next/link"
import {useRouter} from "next/router"
pnpm create next-app myblog
typescript > No
eslint > No
kita pakai css bawaan
//index.jsx
import styles from "../styles/Home.module.css"
export default function Home (){
return (
<main className={styles.main}>
<h1>My Blog</h1>
</main>
)
}
selanjutnya kita akan melakukan fetching data,
import styles from "../styles/Home.module.css"
export default function Home ({data, page}){
return (
<main className={styles.main}>
<h1>My Blog {page}</h1>
</main>
)
}
export async function getServerSideProps(ctx){
console.info(ctx)
const result = await fetch("https://jsonplaceholder.typicode.com/posts?_page=" + ctx.query.page)
const data = await result.json()
return {
props : {
data: data,
page : ctx.query.page || 1
}
}
}
//index.jsx
import styles from "../styles/Home.module.css"
export default function Home ({data, page}){
return (
<main className={styles.main}>
<h1>My Blog {page}</h1>
<div className="styles.cardWrapper">
{data.map((e)=>(
<div key={e.id}>
<h3>{e.title}</h3>
<p>{e.body}</p>
</div>
))}
</div>
</main>
)
}
export async function getServerSideProps(ctx){
console.info(ctx)
const result = await fetch("https://jsonplaceholder.typicode.com/posts?_page=" + ctx.query.page)
const data = await result.json()
return {
props : {
data: data,
page : ctx.query.page || 1
}
}
}
kita sudah berhasil menampilkan data jsonnya sekarang kita akan menampilkan gambarnya dari picsum.photos
//index.jsx
import styles from "../styles/Home.module.css"
export default function Home ({data, page}){
return (
<main className={styles.main}>
<h1>My Blog {page}</h1>
<div className="styles.cardWrapper">
{data.map((e)=>(
<div key={e.id}>
<img src={ `https://picsum.photos/seed/${e.id}/500/300` } alt={e.title} />
<h3>{e.id} . {e.title}</h3>
<p>{e.body}</p>
</div>
))}
</div>
</main>
)
}
export async function getServerSideProps(ctx){
console.info(ctx)
const result = await fetch("https://jsonplaceholder.typicode.com/posts?_page=" + ctx.query.page)
const data = await result.json()
return {
props : {
data: data,
page : ctx.query.page || 1
}
}
}
selanjutnya kita akan menampilkan gambar dengan images next js
//next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
reactStrictMode: true,
images : {
remotePatterns : [
{
protocol : 'https',
hostname : 'picsum.photos'
}
]
}
}
module.exports = nextConfig
import styles from "../styles/Home.module.css"
import Image from "next/image"
export default function Home ({data, page}){
return (
<main className={styles.main}>
<h1>My Blog {page}</h1>
<div className="styles.cardWrapper">
{data.map((e)=>(
<div key={e.id} className={styles.blogCard}>
<Image
src={ `https://picsum.photos/seed/${e.id}/200/200` }
alt={e.title}
width={200}
height={200}
/>
<h3>{e.id} . {e.title}</h3>
<p>{e.body}</p>
</div>
))}
</div>
</main>
)
}
export async function getServerSideProps(ctx){
console.info(ctx)
const result = await fetch("https://jsonplaceholder.typicode.com/posts?_page=" + ctx.query.page)
const data = await result.json()
return {
props : {
data: data,
page : ctx.query.page || 1
}
}
}
akan ada pesan error karena kita mengganti config js, jadi servernya kita matikan dulu, kemudian start ulang.
selanjutnya kita akan menampilkan prev dan next dibagian bawah page kita
//index.jsx
import styles from "../styles/Home.module.css"
import Image from "next/image"
import {useRouter} from "next/router"
export default function Home ({data, page}){
const router = useRouter()
//function untuk pagination
const nextPage = ()=>{
router.push(`/?page=${page + 1}`)
}
return (
<main className={styles.main}>
<h1>My Blog {page}</h1>
<div className="styles.cardWrapper">
{data.map((e)=>(
<div key={e.id} className={styles.blogCard}>
<Image
src={ `https://picsum.photos/seed/${e.id}/200/200` }
alt={e.title}
width={200}
height={200}
/>
<h3>{e.id} . {e.title}</h3>
<p>{e.body}</p>
</div>
))}
</div>
<div className={styles.btnPagination}>
<button>prev</button>
<button onClick={nextPage}>next</button>
</div>
</main>
)
}
export async function getServerSideProps(ctx){
console.info(ctx)
const result = await fetch("https://jsonplaceholder.typicode.com/posts?_page=" + ctx.query.page)
const data = await result.json()
return {
props : {
data: data,
page : parseInt(ctx.query.page) || 1
}
}
}
sekarang kita ke function prev page
import styles from "../styles/Home.module.css"
import Image from "next/image"
import {useRouter} from "next/router"
export default function Home ({data, page}){
const router = useRouter()
//function untuk pagination
const nextPage = ()=>{
router.push(`/?page=${page + 1}`)
}
const prevPage =()=>{
if (page==1){
return
}
router.push(`/?page=${page - 1}`)
}
return (
<main className={styles.main}>
<h1>My Blog {page}</h1>
<div className="styles.cardWrapper">
{data.map((e)=>(
<div key={e.id} className={styles.blogCard}>
<Image
src={ `https://picsum.photos/seed/${e.id}/200/200` }
alt={e.title}
width={200}
height={200}
/>
<h3>{e.id} . {e.title}</h3>
<p>{e.body}</p>
</div>
))}
</div>
<div className={styles.btnPagination}>
<button onClick={prevPage}>prev</button>
<button onClick={nextPage}>next</button>
</div>
</main>
)
}
export async function getServerSideProps(ctx){
console.info(ctx)
const result = await fetch("https://jsonplaceholder.typicode.com/posts?_page=" + ctx.query.page)
const data = await result.json()
return {
props : {
data: data,
page : parseInt(ctx.query.page) || 1
}
}
}
selanjutnya kita akan buat Link tag a yang akan mengarahkan detailnya, sebelumnya buat folder detail dan files [id].jsx
//detail > [id.jsx]
import styles from "../../styles/Home.module.css"
import Image from "next/image"
import { useRouter } from "next/router"
export default function Details ({data}){
const router = useRouter()
return (
<main className={styles.main}>
<h1>{data.title}</h1>
<Image
src={`https://picsum.photos/seed/${data.id}/900/500`}
width={900}
height ={500}
alt ={data.title}
/>
<p>{data.body}</p>
<button onClick={()=>{router.back()}}>back</button>
</main>
)
}
export async function getServerSideProps(ctx){
const result =await fetch("https://jsonplaceholder.typicode.com/posts/" + ctx.params.id)
const data = await result.json()
return {
props : {
data : data
}
}
}
tambahkan Link
//index.jsx
import styles from "../styles/Home.module.css"
import Image from "next/image"
import Link from "next/link"
import {useRouter} from "next/router"
export default function Home ({data, page}){
const router = useRouter()
//function untuk pagination
const nextPage = ()=>{
router.push(`/?page=${page + 1}`)
}
const prevPage =()=>{
if (page==1){
return
}
router.push(`/?page=${page - 1}`)
}
return (
<main className={styles.main}>
<h1>My Blog {page}</h1>
<div className="styles.cardWrapper">
{data.map((e)=>(
<div key={e.id} className={styles.blogCard}>
<Image
src={ `https://picsum.photos/seed/${e.id}/200/200` }
alt={e.title}
width={200}
height={200}
/>
<h3>{e.id} . {e.title}</h3>
<p>{e.body}</p>
<Link href={`/details/${e.id}`}>Detail</Link>
</div>
))}
</div>
<div className={styles.btnPagination}>
<button onClick={prevPage}>prev</button>
<button onClick={nextPage}>next</button>
</div>
</main>
)
}
export async function getServerSideProps(ctx){
console.info(ctx)
const result = await fetch("https://jsonplaceholder.typicode.com/posts?_page=" + ctx.query.page)
const data = await result.json()
return {
props : {
data: data,
page : parseInt(ctx.query.page) || 1
}
}
}
selanjutnya kita akan menambahkan css
//Home.module.css
.main {
min-height: 100vh;
padding: 4rem 0;
flex: 1;
display: flex;
flex-direction: column;
justify-content: center;
align-items: flex-start;
max-width: 900px;
margin: 0 auto;
}
.cardWrapper {
display: flex;
flex-direction: column;
gap: 40px;
}
.blogCard {
display: flex;
gap: 20px;
padding: 20px;
border: 1px dashed whitesmoke;
}
Posted on November 8, 2022
Join Our Newsletter. No Spam, Only the good stuff.
Sign up to receive the latest update from our blog.
Related
November 29, 2024