I developed Next.js CRUD app with microCMS.
My app completely work on my local side. But unfortunately when uploading my app to vercel, it won’t work correctly. Every time I update values, it won’t change like below.
Here’s my code of update.js and index.js.
I added some update query on createClient.
lib/client.js
<code>import { createClient } from 'microcms-js-sdk';
export const client = createClient({
serviceDomain: process.env.NEXT_PUBLIC_MICROCMS_SERVICE_DOMAIN,
apiKey: process.env.NEXT_PUBLIC_MICROCMS_API_KEY,
retry: true,
customFetch: (input, init) => {
const newInput = new URL(input)
const time = new Date()
newInput.searchParams.set('cacheclearparam', `${time.getMinutes()}`)
return fetch(newInput.href, init)
},
});
</code>
<code>import { createClient } from 'microcms-js-sdk';
export const client = createClient({
serviceDomain: process.env.NEXT_PUBLIC_MICROCMS_SERVICE_DOMAIN,
apiKey: process.env.NEXT_PUBLIC_MICROCMS_API_KEY,
retry: true,
customFetch: (input, init) => {
const newInput = new URL(input)
const time = new Date()
newInput.searchParams.set('cacheclearparam', `${time.getMinutes()}`)
return fetch(newInput.href, init)
},
});
</code>
import { createClient } from 'microcms-js-sdk';
export const client = createClient({
serviceDomain: process.env.NEXT_PUBLIC_MICROCMS_SERVICE_DOMAIN,
apiKey: process.env.NEXT_PUBLIC_MICROCMS_API_KEY,
retry: true,
customFetch: (input, init) => {
const newInput = new URL(input)
const time = new Date()
newInput.searchParams.set('cacheclearparam', `${time.getMinutes()}`)
return fetch(newInput.href, init)
},
});
pages/update.js
<code>import Link from "next/link";
import { client } from "@/libs/client";
import { useRouter } from "next/router";
import React, { useState } from "react";
export default function Update ({ blog }) {
const router = useRouter()
const id = blog.id;
const [title, setTitle] = useState(blog.title);
const [content, setContent] = useState(blog.content);
const remove_html = text => {
return text ? text.replace(/(<([^>]+)>)/gi, '') : null;
}
async function update(event) {
event.preventDefault()
client.update({
endpoint: "blogs",
content: {
title: title,
content: content,
},
contentId: id
}).then((res) => {
if (res.status === 401) {
alert("編集ができませんでした。")
} else {
alert("編集されました。")
router.push(`/`)
}
})
}
return (
<>
<div className='main'>
<h1 className=''>編集ページ</h1>
{/* TOPに戻るボタン */}
<div className="top">
<Link href="/" className="">
<button className="">Topに戻る</button>
</Link>
</div>
<div className="contents">
<div>
<form onSubmit={ update }>
<div>
<h2>タイトル</h2>
<input name="title" type="text" defaultValue={blog.title} onChange={(event) => setTitle(event.target.value)} />
</div>
<div>
<h2>コンテンツ</h2>
<textarea name="content" defaultValue={remove_html(blog.content)} onChange={(event) => setContent(event.target.value)} ></textarea>
</div>
<button type="submit">
<p>登録する</p>
</button>
</form>
</div>
</div>
</div>
</>
);
}
export const getStaticPaths = async () => {
const data = await client.get({ endpoint: "blogs" });
const paths = data.contents.map((content) => `/blog/${content.id}/update`);
return { paths, fallback: false };
};
export const getStaticProps = async (context) => {
const id = context.params.id;
const data = await client.get({ endpoint: "blogs", contentId: id });
return {
props: {
blog: data,
},
};
};
</code>
<code>import Link from "next/link";
import { client } from "@/libs/client";
import { useRouter } from "next/router";
import React, { useState } from "react";
export default function Update ({ blog }) {
const router = useRouter()
const id = blog.id;
const [title, setTitle] = useState(blog.title);
const [content, setContent] = useState(blog.content);
const remove_html = text => {
return text ? text.replace(/(<([^>]+)>)/gi, '') : null;
}
async function update(event) {
event.preventDefault()
client.update({
endpoint: "blogs",
content: {
title: title,
content: content,
},
contentId: id
}).then((res) => {
if (res.status === 401) {
alert("編集ができませんでした。")
} else {
alert("編集されました。")
router.push(`/`)
}
})
}
return (
<>
<div className='main'>
<h1 className=''>編集ページ</h1>
{/* TOPに戻るボタン */}
<div className="top">
<Link href="/" className="">
<button className="">Topに戻る</button>
</Link>
</div>
<div className="contents">
<div>
<form onSubmit={ update }>
<div>
<h2>タイトル</h2>
<input name="title" type="text" defaultValue={blog.title} onChange={(event) => setTitle(event.target.value)} />
</div>
<div>
<h2>コンテンツ</h2>
<textarea name="content" defaultValue={remove_html(blog.content)} onChange={(event) => setContent(event.target.value)} ></textarea>
</div>
<button type="submit">
<p>登録する</p>
</button>
</form>
</div>
</div>
</div>
</>
);
}
export const getStaticPaths = async () => {
const data = await client.get({ endpoint: "blogs" });
const paths = data.contents.map((content) => `/blog/${content.id}/update`);
return { paths, fallback: false };
};
export const getStaticProps = async (context) => {
const id = context.params.id;
const data = await client.get({ endpoint: "blogs", contentId: id });
return {
props: {
blog: data,
},
};
};
</code>
import Link from "next/link";
import { client } from "@/libs/client";
import { useRouter } from "next/router";
import React, { useState } from "react";
export default function Update ({ blog }) {
const router = useRouter()
const id = blog.id;
const [title, setTitle] = useState(blog.title);
const [content, setContent] = useState(blog.content);
const remove_html = text => {
return text ? text.replace(/(<([^>]+)>)/gi, '') : null;
}
async function update(event) {
event.preventDefault()
client.update({
endpoint: "blogs",
content: {
title: title,
content: content,
},
contentId: id
}).then((res) => {
if (res.status === 401) {
alert("編集ができませんでした。")
} else {
alert("編集されました。")
router.push(`/`)
}
})
}
return (
<>
<div className='main'>
<h1 className=''>編集ページ</h1>
{/* TOPに戻るボタン */}
<div className="top">
<Link href="/" className="">
<button className="">Topに戻る</button>
</Link>
</div>
<div className="contents">
<div>
<form onSubmit={ update }>
<div>
<h2>タイトル</h2>
<input name="title" type="text" defaultValue={blog.title} onChange={(event) => setTitle(event.target.value)} />
</div>
<div>
<h2>コンテンツ</h2>
<textarea name="content" defaultValue={remove_html(blog.content)} onChange={(event) => setContent(event.target.value)} ></textarea>
</div>
<button type="submit">
<p>登録する</p>
</button>
</form>
</div>
</div>
</div>
</>
);
}
export const getStaticPaths = async () => {
const data = await client.get({ endpoint: "blogs" });
const paths = data.contents.map((content) => `/blog/${content.id}/update`);
return { paths, fallback: false };
};
export const getStaticProps = async (context) => {
const id = context.params.id;
const data = await client.get({ endpoint: "blogs", contentId: id });
return {
props: {
blog: data,
},
};
};
pages/index.js
<code>import Head from "next/head";
import Link from "next/link";
import styles from "@/styles/Home.module.css";
import { client } from '@/libs/client'
import { useRouter } from "next/router";
export default function Home({ blog }) {
const router = useRouter();
async function deleteItem(event) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const id = formData.get('id');
client.delete({
endpoint: 'blogs',
contentId: id,
})
.then((res) => {
alert("正常に削除されました。")
router.push(`/`)
})
.catch((err) => {
alert("削除できませんでした。"+err)
})
}
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<div id="new-blog">
<Link href="/blog/create" className="">
<button className="">ブログを作成</button>
</Link>
</div>
<div id="blog-list">
{blog.map((blog) => (
<div className={styles.div}>
<ul className={styles.ul}>
<li className={styles.li} key={blog.id}>
<Link href={`/blog/${blog.id}`}>{blog.title}</Link>
<Link href={`/blog/${blog.id}/update`} className="">
<button className="">編集</button>
</Link>
<form onSubmit={ deleteItem }>
<input type="hidden" name="id" value={blog.id} />
<input type="submit" value="削除" />
</form>
</li>
</ul>
</div>
))}
</div>
</main>
</>
)
}
export const getStaticProps = async () => {
const data = await client.get({
endpoint: 'blogs',
})
return {
props: {
blog: data.contents,
},
}
}
</code>
<code>import Head from "next/head";
import Link from "next/link";
import styles from "@/styles/Home.module.css";
import { client } from '@/libs/client'
import { useRouter } from "next/router";
export default function Home({ blog }) {
const router = useRouter();
async function deleteItem(event) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const id = formData.get('id');
client.delete({
endpoint: 'blogs',
contentId: id,
})
.then((res) => {
alert("正常に削除されました。")
router.push(`/`)
})
.catch((err) => {
alert("削除できませんでした。"+err)
})
}
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<div id="new-blog">
<Link href="/blog/create" className="">
<button className="">ブログを作成</button>
</Link>
</div>
<div id="blog-list">
{blog.map((blog) => (
<div className={styles.div}>
<ul className={styles.ul}>
<li className={styles.li} key={blog.id}>
<Link href={`/blog/${blog.id}`}>{blog.title}</Link>
<Link href={`/blog/${blog.id}/update`} className="">
<button className="">編集</button>
</Link>
<form onSubmit={ deleteItem }>
<input type="hidden" name="id" value={blog.id} />
<input type="submit" value="削除" />
</form>
</li>
</ul>
</div>
))}
</div>
</main>
</>
)
}
export const getStaticProps = async () => {
const data = await client.get({
endpoint: 'blogs',
})
return {
props: {
blog: data.contents,
},
}
}
</code>
import Head from "next/head";
import Link from "next/link";
import styles from "@/styles/Home.module.css";
import { client } from '@/libs/client'
import { useRouter } from "next/router";
export default function Home({ blog }) {
const router = useRouter();
async function deleteItem(event) {
event.preventDefault();
const formData = new FormData(event.currentTarget);
const id = formData.get('id');
client.delete({
endpoint: 'blogs',
contentId: id,
})
.then((res) => {
alert("正常に削除されました。")
router.push(`/`)
})
.catch((err) => {
alert("削除できませんでした。"+err)
})
}
return (
<>
<Head>
<title>Create Next App</title>
<meta name="description" content="Generated by create next app" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<link rel="icon" href="/favicon.ico" />
</Head>
<main className={styles.main}>
<div id="new-blog">
<Link href="/blog/create" className="">
<button className="">ブログを作成</button>
</Link>
</div>
<div id="blog-list">
{blog.map((blog) => (
<div className={styles.div}>
<ul className={styles.ul}>
<li className={styles.li} key={blog.id}>
<Link href={`/blog/${blog.id}`}>{blog.title}</Link>
<Link href={`/blog/${blog.id}/update`} className="">
<button className="">編集</button>
</Link>
<form onSubmit={ deleteItem }>
<input type="hidden" name="id" value={blog.id} />
<input type="submit" value="削除" />
</form>
</li>
</ul>
</div>
))}
</div>
</main>
</>
)
}
export const getStaticProps = async () => {
const data = await client.get({
endpoint: 'blogs',
})
return {
props: {
blog: data.contents,
},
}
}