😍Sử dụng Query Composer để lấy dữ liệu (ok)
Example 1


query GetMenuId {
menu(id: "17", idType: DATABASE_ID) {
menuItems {
edges {
node {
label
uri
url
}
}
}
}
}
apis\index.ts
export async function getMenuId(id:number) {
const data = await fetchAPI(
`
query menuId {
menu(id: ${id}, idType: DATABASE_ID) {
menuItems {
edges {
node {
label
uri
url
}
}
}
}
}
`
);
return data?.menu?.menuItems?.edges;
}
pages\index.tsx
export const getStaticProps: GetStaticProps = async () => {
const MenuId = await getMenuId(17);
return {
props: { MenuId },
revalidate: 10,
};
}
console.log(MenuId);

Example 2

query GET_MENUS {
headerMenus: menuItems(where: {location: PRIMARY}) {
edges {
node {
id
label
url
path
}
}
}
footerMenu: menuItems(where: {location: FOOTER_MENU}) {
edges {
node {
id
label
path
}
}
}
}
Hoặc dùng Fragment
query GET_MENUS {
headerMenus: menuItems(where: {location: PRIMARY}) {
edges {
node {
...MenuItem
}
}
}
footerMenu: menuItems(where: {location: FOOTER_MENU}) {
edges {
node {
...MenuItem
}
}
}
}
fragment MenuItem on MenuItem {
id
label
url
path
}
Example 3 sử dụng api graphql để làm menu
fetch('https://content.wpgraphql.com/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `
{
generalSettings {
url
}
}
`,
}),
})
.then(res => res.json())
.then(res => console.log(res.data))

components\header.tsx
import Link from "next/link";
export default function Header({ menus }: any) {
return (
<header className="text-gray-600 body-font">
<div className="container flex flex-col flex-wrap items-center p-5 mx-auto md:flex-row">
<nav className="flex flex-wrap items-center text-base lg:w-2/5 md:ml-auto">
{
menus.map((menu:any,index:number) => (
<Link key={index} href={`${menu?.node?.uri}`} className="mr-5 hover:text-gray-900">{menu?.node?.label}</Link>
))
}
</nav>
<a className="flex items-center order-first mb-4 font-medium text-gray-900 lg:order-none lg:w-1/5 title-font lg:items-center lg:justify-center md:mb-0">
<svg xmlns="http://www.w3.org/2000/svg" fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" className="w-10 h-10 p-2 text-white bg-indigo-500 rounded-full" viewBox="0 0 24 24">
<path d="M12 2L2 7l10 5 10-5-10-5zM2 17l10 5 10-5M2 12l10 5 10-5"></path>
</svg>
<span className="ml-3 text-xl">Tailblocks</span>
</a>
<div className="inline-flex ml-5 lg:w-2/5 lg:justify-end lg:ml-0">
<button className="inline-flex items-center px-3 py-1 mt-4 text-base bg-gray-100 border-0 rounded focus:outline-none hover:bg-gray-200 md:mt-0">Button
<svg fill="none" stroke="currentColor" strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" className="w-4 h-4 ml-1" viewBox="0 0 24 24">
<path d="M5 12h14M12 5l7 7-7 7"></path>
</svg>
</button>
</div>
</div>
</header>
);
}

components\layout.tsx
import Header from "./header";
import Main from "./main";
import Footer from "./footer";
import { useEffect, useState } from "react";
export default function Layout({ children }: any) {
const [menu, setMenu] = useState([]);
useEffect(() => {
fetch('https://wpclidemo.dev/graphql', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify({
query: `
{
menu(id: 17, idType: DATABASE_ID) {
menuItems {
edges {
node {
label
uri
url
}
}
}
}
}
`,
}),
})
.then(res => res.json())
.then(res => setMenu(res.data.menu.menuItems.edges))
});
return (
<>
<Header menus={menu} />
<Main>{children}</Main>
<Footer />
</>
);
}
Last updated
Was this helpful?