{"id":7987,"date":"2026-08-15T11:39:31","date_gmt":"2026-08-15T02:39:31","guid":{"rendered":"https:\/\/www.freelifemakers.org\/wordpress\/?p=7987"},"modified":"2026-08-16T12:27:25","modified_gmt":"2026-08-16T03:27:25","slug":"nextjs-sns-server-4","status":"publish","type":"post","link":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/15\/nextjs-sns-server-4\/","title":{"rendered":"[nextjs]SNS Server-4(myapp14)"},"content":{"rendered":"\n<p>\ud83d\udc49\ud83c\udffb myapp13\ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c user1@freelifemakers.com\uc5d0\uc11c user1@yourhost.domain.org\ub97c \ud314\ub85c\uc6b0 \ud588\uc2b5\ub2c8\ub2e4.<br>In the myapp13 project, user1@freelifemakers.com followed user1@yourhost.domain.org.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uadf8\ub9ac\uace0 user1@yourhost.domain.org\ub85c \ub85c\uadf8\uc778\ud574\uc11c \uae00\uc744 \uc4f8 \uacbd\uc6b0user1@freelifemakers.com\uc5d0 \ubc30\ub2ec\ub418\uace0 pinafore.social\uc5d0\uc11c\ub3c4 \ud655\uc778 \uac00\ub2a5\ud55c\uc9c0 \ud14c\uc2a4\ud2b8 \ud588\uc5c8\uc2b5\ub2c8\ub2e4.<br>I also tested whether logging in as user1@yourhost.domain.org and posting a message would result in delivery to user1@freelifemakers.com and visibility on pinafore.social.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uc774\ubc88 myapp14\ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c\ub294 \ubc18\ub300\ub85c user1@yourhost.domain.org\uac00 user1@freelifemakers.com\uc744 \ud314\ub85c\uc6b0 \ud569\ub2c8\ub2e4.<br>In this myapp14 project, conversely, user1@yourhost.domain.org follows user1@freelifemakers.com.<\/p>\n\n\n\n<p>\ud83d\udc49\ud83c\udffb \uadf8\ub9ac\uace0 user1@freelifemakers.com\uc5d0\uc11c \uae00\uc744 \uc4f8 \uacbd\uc6b0 user1@yourhost.domain.org\ub85c \uae00\uc774 \ubc30\ub2ec\ub418\ub294\uc9c0 \ud655\uc778\ud569\ub2c8\ub2e4.<br>Also, verify whether messages sent from user1@freelifemakers.com are delivered to user1@yourhost.domain.org.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udcc1 \ud504\ub85c\uc81d\ud2b8 \uc124\uce58(myapp14) ,HTTPS\uc124\uc815<br>Project Installation (myapp14), HTTPS Configuration<\/p>\n\n\n\n<p>\u2714\ufe0f nextjs\ud504\ub85c\uc81d\ud2b8\uc124\uce58,sqlite\uc124\uce58,Caddy\uc124\uce58 \ubc0f \uc124\uc815<br>Next.js project setup, SQLite installation, and Caddy installation and configuration<\/p>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-freelifemakers-org wp-block-embed-freelifemakers-org\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"HZK4HmAhnX\"><a href=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/10\/nextjs-dns-caddy\/\">[nextjs]nextjs+domain(ddns)+https(caddy)<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;[nextjs]nextjs+domain(ddns)+https(caddy)&#8221; &#8212; freelifemakers.org\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/10\/nextjs-dns-caddy\/embed\/#?secret=rGJzowHGFc#?secret=HZK4HmAhnX\" data-secret=\"HZK4HmAhnX\" width=\"560\" height=\"315\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<figure class=\"wp-block-embed is-type-wp-embed is-provider-freelifemakers-org wp-block-embed-freelifemakers-org\"><div class=\"wp-block-embed__wrapper\">\n<blockquote class=\"wp-embedded-content\" data-secret=\"WiKJyYlet7\"><a href=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/14\/nextjs-sns-server-3\/\">[nextjs]SNS Server-3<\/a><\/blockquote><iframe loading=\"lazy\" class=\"wp-embedded-content\" sandbox=\"allow-scripts\" security=\"restricted\" style=\"position: absolute; visibility: hidden;\" title=\"&#8220;[nextjs]SNS Server-3&#8221; &#8212; freelifemakers.org\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/2026\/08\/14\/nextjs-sns-server-3\/embed\/#?secret=wnefzAJlFb#?secret=WiKJyYlet7\" data-secret=\"WiKJyYlet7\" width=\"560\" height=\"315\" frameborder=\"0\" marginwidth=\"0\" marginheight=\"0\" scrolling=\"no\"><\/iframe>\n<\/div><\/figure>\n\n\n\n<p>\ud83d\udcc1 \ud504\ub85c\uc81d\ud2b8 \uad6c\uc870 \/ Project Structure<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>myapp12\/  \n\u251c\u2500\u2500 app\/  (Next.js App Router)\n\u2502   \u251c\u2500\u2500 api\/posts\/route.ts     -&gt; \uae00 \uc4f0\uae30 API \/ Writing API\n\u2502   \u251c\u2500\u2500 api\/follow\/route.ts    -&gt; \ud314\ub85c\uc6b0 API(\uc784\uc2dc) \/ Follow API(temporary)\n\u2502   \u251c\u2500\u2500 users\/&#91;username]\/\n\u2502   \u2502   \u251c\u2500\u2500 route.ts           -&gt; Actor\uc815\ubcf4 \/ Acotr Information\n\u2502   \u2502   \u251c\u2500\u2500 inbox\/route.ts     -&gt; Inbox\n\u2502   \u2502   \u2514\u2500\u2500 outbox\/route.ts    -&gt; outbox\n\u2502   \u251c\u2500\u2500 layout.tsx, page.tsx, globals.css\n\u2502   \u2514\u2500\u2500 favicon.ico\n\u251c\u2500\u2500 lib\/\n\u2502   \u251c\u2500\u2500 ap.ts                  -&gt; Follow Accept\n\u2502   \u2514\u2500\u2500 db.ts                  -&gt; DB connection\n\u251c\u2500\u2500 data\/\n\u2502   \u2514\u2500\u2500 keys\/                  -&gt; private.pem, public.pem\n\u251c\u2500\u2500 data.sqlite                -&gt; Database\n\u251c\u2500\u2500 Caddyfile                  -&gt; https \n\u2514\u2500\u2500 package.json<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \ucf54\ub4dc \uc791\uc131 \/ Writing code<\/p>\n\n\n\n<p>\u2714\ufe0f<code>sendFollow<\/code>\u00a0\ud568\uc218 \ucd94\uac00 \/ Add sendFollow function<\/p>\n\n\n\n<p>&#8212; myapp14\/lib\/ap.ts<\/p>\n\n\n\n<p>&#8212; \uc694\uccad\uc744 \ubcf4\ub0bc\ub54c \uadf8\ub0e5 fetch\ub85c\ubcf4\ub0b4\uba74 gotosocial\uc774 401 Unauthorized \uc5d0\ub7ec\ub97c \ubc1c\uc0dd \uc2dc\ud0b5\ub2c8\ub2e4.<br>If you send a request using just <code>fetch<\/code>, GoToSocial returns a 401 Unauthorized error.<\/p>\n\n\n\n<p>&#8212; \uadf8\ub798\uc11c private key\ub85c \uc0ac\uc778\ud574\uc11c \ubcf4\ub0c5\ub2c8\ub2e4.<br>So, it is signed with a private key and sent.<\/p>\n\n\n\n<p>&#8212; sendFollow\ub85c Follow \uc694\uccad \ubcf4\ub0b4\uae30<br>Send a follow request using sendFollow.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export async function sendFollow(toInbox: string, targetActor: string, username: string) {\n  const actorId = `https:\/\/${DOMAIN}\/users\/${username}`;\n  const followId = `${actorId}\/follows\/${Date.now()}`;\n  \n  const followDoc = {\n    '@context': 'https:\/\/www.w3.org\/ns\/activitystreams',\n    id: followId,\n    type: 'Follow',\n    actor: actorId,\n    object: targetActor\n  };\n\n  const body = JSON.stringify(followDoc);\n  const url = new URL(toInbox);\n  \n  const digest = `SHA-256=${crypto.createHash('sha256').update(body).digest('base64')}`;\n  const date = new Date().toUTCString();\n  const signingString = `(request-target): post ${url.pathname}\\nhost: ${url.host}\\ndate: ${date}\\ndigest: ${digest}`;\n  \n  const signer = crypto.createSign('sha256');\n  signer.update(signingString);\n  const signature = signer.sign(PRIVATE_KEY, 'base64');\n\n  const keyId = `${actorId}#main-key`;\n  const sigHeader = `keyId=\"${keyId}\",headers=\"(request-target) host date digest\",signature=\"${signature}\"`;\n\n  console.log(`\u27a1\ufe0f &#91;${username}] Follow \uc804\uc1a1 \/ Follow sent -> ${toInbox} (${targetActor})`);\n\n  const res = await fetch(toInbox, {\n    method: 'POST',\n    headers: {\n      'Content-Type': 'application\/activity+json',\n      'Date': date,\n      'Digest': digest,\n      'Signature': sigHeader,\n      'Host': url.host\n    },\n    body\n  });\n\n  const text = await res.text();\n  console.log(`\ud83d\udcec Follow \uacb0\uacfc \/ Follow result: ${res.status}`, text);\n  return { ok: res.ok, status: res.status, text, followDoc };\n}<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f signedFetch \ud568\uc218 \ucd94\uac00<br>Add signedFetch function<\/p>\n\n\n\n<p>&#8212; myapp14\/lib\/ap.ts<\/p>\n\n\n\n<p>&#8212; \uc694\uccad\uc744 \ubcf4\ub0bc\ub54c \uadf8\ub0e5 fetch\ub85c\ubcf4\ub0b4\uba74 gotosocial\uc774 401 Unauthorized \uc5d0\ub7ec\ub97c \ubc1c\uc0dd \uc2dc\ud0b5\ub2c8\ub2e4.<br>If you send a request using just <code>fetch<\/code>, GoToSocial returns a 401 Unauthorized error.<\/p>\n\n\n\n<p>&#8212; \uadf8\ub798\uc11c private key\ub85c \uc0ac\uc778\ud574\uc11c \ubcf4\ub0c5\ub2c8\ub2e4.<br>So, it is signed with a private key and sent.<\/p>\n\n\n\n<p>&#8212; signedFetch\ub85c \uc0c1\ub300\ubc29 inbox \ucc3e\ub294 \uae30\ub2a5<br>Functionality to locate the recipient&#8217;s inbox using signedFetch<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>export async function signedFetch(urlStr: string, username: string) {\n  const actorId = `https:\/\/${DOMAIN}\/users\/${username}`;\n  const url = new URL(urlStr);\n  const date = new Date().toUTCString();\n  const signingString = `(request-target): get ${url.pathname}\\nhost: ${url.host}\\ndate: ${date}`;\n  \n  const signer = crypto.createSign('sha256');\n  signer.update(signingString);\n  const signature = signer.sign(PRIVATE_KEY, 'base64');\n\n  const keyId = `${actorId}#main-key`;\n  const sigHeader = `keyId=\"${keyId}\",headers=\"(request-target) host date\",signature=\"${signature}\"`;\n\n  console.log(`\ud83d\udd10 Signed GET -> ${urlStr}`);\n\n  return fetch(urlStr, {\n    headers: {\n      'Accept': 'application\/activity+json',\n      'Date': date,\n      'Signature': sigHeader,\n      'Host': url.host\n    }\n  });\n}<\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f follow\ub77c\uc6b0\ud2b8 \ucd94\uac00<br>Add follow route<\/p>\n\n\n\n<p>&#8212; myapp14\/app\/api\/follow\/route.ts<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/\/ myapp14\/app\/api\/follow\/route.ts\nimport { sendFollow, signedFetch } from '@\/lib\/ap';\n\n\/\/ myapp14 - Follow \ubcf4\ub0b4\uae30 API \u2705\n\/\/ POST \/api\/follow\nexport async function POST(req: Request) {\n  try {\n    const { username = 'user1', target } = await req.json();\n    if (!target) return Response.json({ error: 'target \ud544\uc694' }, { status: 400 });\n\n    console.log(`\u27a1\ufe0f \ud314\ub85c\uc6b0 \uc2dc\ub3c4 \/ Follow attempt: ${username} -> ${target}`);\n\n    \/\/ 1. \uc0c1\ub300\ubc29 inbox \ucc3e\uae30 - \uc11c\uba85\ub41c GET\uc73c\ub85c! \/ Find the inbox with a signed GET request\n    const actorRes = await signedFetch(target, username);\n    \n    if (!actorRes.ok) {\n      const t = await actorRes.text();\n      return Response.json({ error: `\uc0c1\ub300\ubc29 \uc870\ud68c \uc2e4\ud328 \/ Failed to look up the other party. ${actorRes.status}`, body: t }, { status: 400 });\n    }\n\n    const actor = await actorRes.json();\n    const inbox = actor.inbox;\n    console.log(`\ud83d\udcec inbox \ucc3e\uc74c \/ Found inbox: ${inbox}`);\n\n    \/\/ 2. Follow \uc804\uc1a1 \/ Send Follow\n    const result = await sendFollow(inbox, target, username);\n\n    return Response.json({ \n      ok: result.ok, \n      inbox, \n      target,\n      result: result.text,\n      follow: result.followDoc\n    });\n\n  } catch (e: any) {\n    console.error('follow \uc5d0\ub7ec \/ Follow error:', e);\n    return Response.json({ error: e.message }, { status: 500 });\n  }\n}<\/code><\/pre>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<p>\ud83d\udcc1 \ub0b4 \uc11c\ubc84\uc5d0\uc11c user1@freelifemakers.com\ub97c \ud314\ub85c\uc6b0\ud558\uae30<br>Follow user1@freelifemakers.com from my server<\/p>\n\n\n\n<p>\u2714\ufe0f \ud314\ub85c\uc6b0 \ud558\uae30 \uc704\ud574\uc11c\ub294 pinafore\uc5d0 \ub85c\uadf8\uc778\ud574\uc57c\ud558\uc9c0\ub9cc \uc544\uc9c1 \ub85c\uadf8\uc778 \uae30\ub2a5\uc744 \uad6c\ud604\ud558\uc9c0 \uc54a\uc558\uc2b5\ub2c8\ub2e4.<br>You need to log in to Pinafore to follow, but the login functionality hasn&#8217;t been implemented yet.<\/p>\n\n\n\n<p>\u2714\ufe0f \uadf8\ub798\uc11c \ud130\ubbf8\ub110\uc5d0\uc11c curl \uba85\ub839\uc5b4\ub85c \ub0b4 \ub85c\uceec\uc11c\ubc84(yourhost.domain.org)\uc5d0\uc11c user1@freelifemakers.com\ub97c \ud314\ub85c\uc6b0\ud569\ub2c8\ub2e4.<br>So, I use the <code>curl<\/code> command in the terminal to follow <code>user1@freelifemakers.com<\/code> from my local server (<code>yourhost.domain.org<\/code>).<\/p>\n\n\n\n<p>\u2714\ufe0f \/follow \ub77c\uc6b0\ud2b8\uac00 -d \ud30c\ub77c\uba54\ud130\uc758 \uc815\ubcf4\ub85c \ud314\ub85c\uc6b0\ub97c \uc2dc\ub3c4\ud569\ub2c8\ub2e4.<br>The \/follow route attempts to follow using the information from the -d parameter.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># \ub0b4 \ud130\ubbf8\ub110 \/ My Terminal\n\nfollow % curl -X POST https:\/\/aloy-horizon.duckdns.org\/api\/follow \\\n  -H \"Content-Type: application\/json\" \\\n  -d '{\n    \"username\": \"user1\",\n    \"target\": \"https:\/\/freelifemakers.com\/users\/user1\"\n  }'\n\n{\"ok\":true,\"inbox\":\"https:\/\/freelifemakers.com\/users\/user1\/inbox\",\"target\":\"https:\/\/freelifemakers.com\/users\/user1\",\"result\":\"{\\\"status\\\":\\\"Accepted\\\"}\",\"follow\":{\"@context\":\"https:\/\/www.w3.org\/ns\/activitystreams\",\"id\":\"https:\/\/yourhost.domain.org\/users\/user1\/follows\/1786763495558\",\"type\":\"Follow\",\"actor\":\"https:\/\/yourhost.domain.org\/users\/user1\",\"object\":\"https:\/\/freelifemakers.com\/users\/user1\"}}<\/code><\/pre>\n\n\n\n<pre class=\"wp-block-code\"><code># nextjs \uc11c\ubc84 \ub85c\uadf8 \/ nextjs server log (ok!)\n\n\u27a1\ufe0f &#91;user1] Follow \uc804\uc1a1 -> https:\/\/freelifemakers.com\/users\/user1\/inbox (https:\/\/freelifemakers.com\/users\/user1)\n\ud83d\udcec Follow \uacb0\uacfc: 202 {\"status\":\"Accepted\"}<\/code><\/pre>\n\n\n\n<p>\ud83d\udcc1 \uae00 \ubc30\ub2ec \ud655\uc778 \ud558\uae30 \/ Check for delivered messages<\/p>\n\n\n\n<p>\u2714\ufe0f \uae00\uc774 \ub0b4 \uc11c\ubc84\ub85c \ubc30\ub2ec\ub418\ub294\uc9c0 \ud655\uc778\ud558\uae30\uc704\ud574\uc11c pinafore.social\uc5d0\uc11c \uae00\uc744 \uc368\ubd05\ub2c8\ub2e4.<br>I am writing a post on pinafore.social to check if it gets delivered to my server.<\/p>\n\n\n\n<p>\u2714\ufe0f \uc774\ub54c \ub85c\uadf8\uc778\uc740 user1@freelifemakers.com \uc778\uacbd\uc6b0 \uc785\ub2c8\ub2e4.<br>In this case, the login account is user1@freelifemakers.com.<\/p>\n\n\n\n<figure class=\"wp-block-image size-full\"><img loading=\"lazy\" decoding=\"async\" width=\"800\" height=\"772\" src=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp14-posting-pinafore-jpg.jpg\" alt=\"\" class=\"wp-image-8048\" srcset=\"https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp14-posting-pinafore-jpg.jpg 800w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp14-posting-pinafore-jpg-300x290.jpg 300w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp14-posting-pinafore-jpg-768x741.jpg 768w, https:\/\/www.freelifemakers.org\/wordpress\/wp-content\/uploads\/2026\/08\/myapp14-posting-pinafore-jpg-400x386.jpg 400w\" sizes=\"auto, (max-width: 800px) 100vw, 800px\" \/><figcaption class=\"wp-element-caption\">pinafore<\/figcaption><\/figure>\n\n\n\n<p>\u2714\ufe0f \uae00 \ubc30\ub2ec\ud655\uc778\ud558\uae30(\ub370\uc774\ud130\ubca0\uc774\uc2a4)<br>Check Message Delivery Status (Database)<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>sqlite&gt; select content from posts;\nHello! my SNS!!\nHello! my SNS!!\n<strong>&#91;from: https:\/\/freelifemakers.com\/users\/user1] &lt;p&gt;hello! my follow test!!&lt;\/p&gt;\n&#91;from: https:\/\/freelifemakers.com\/users\/user1] &lt;p&gt;hello my follow test&lt;\/p&gt;<\/strong>\nsqlite&gt; <\/code><\/pre>\n\n\n\n<p>\u2714\ufe0f \uc11c\ubc84 \ub85c\uadf8 \/ Server logs<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\ud83d\udce9 &#91;user1] INBOX: Create https:\/\/freelifemakers.com\/users\/user1\n\ud83d\udcdd &#91;user1] \uc0c8 \uae00 \ub3c4\ucc29 from https:\/\/freelifemakers.com\/users\/user1\n\ub0b4\uc6a9: &lt;p&gt;hello! my follow test!!&lt;\/p&gt;\n\u2705 &#91;user1] \uae00 \uc800\uc7a5 \uc644\ub8cc!\n POST \/users\/user1\/inbox 202 in 26ms (next.js: 15ms, application-code: 11ms)\n\ud83d\udce9 &#91;user1] INBOX: Create https:\/\/freelifemakers.com\/users\/user1\n\ud83d\udcdd &#91;user1] \uc0c8 \uae00 \ub3c4\ucc29 from https:\/\/freelifemakers.com\/users\/user1\n\ub0b4\uc6a9: &lt;p&gt;hello my follow test&lt;\/p&gt;\n\u2705 &#91;user1] \uae00 \uc800\uc7a5 \uc644\ub8cc!\n<\/code><\/pre>\n\n\n\n<p><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\ud83d\udc49\ud83c\udffb myapp13\ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c user1@freelifemakers.com\uc5d0\uc11c user1@yourhost.domain.org\ub97c \ud314\ub85c\uc6b0 \ud588\uc2b5\ub2c8\ub2e4.In the myapp13 project, user1@freelifemakers.com followed user1@yourhost.domain.org. \ud83d\udc49\ud83c\udffb \uadf8\ub9ac\uace0 user1@yourhost.domain.org\ub85c \ub85c\uadf8\uc778\ud574\uc11c \uae00\uc744 \uc4f8 \uacbd\uc6b0user1@freelifemakers.com\uc5d0 \ubc30\ub2ec\ub418\uace0 pinafore.social\uc5d0\uc11c\ub3c4 \ud655\uc778 \uac00\ub2a5\ud55c\uc9c0 \ud14c\uc2a4\ud2b8 \ud588\uc5c8\uc2b5\ub2c8\ub2e4.I also tested whether logging in as user1@yourhost.domain.org and posting a message would result in delivery to user1@freelifemakers.com and visibility on pinafore.social. \ud83d\udc49\ud83c\udffb \uc774\ubc88 myapp14\ud504\ub85c\uc81d\ud2b8\uc5d0\uc11c\ub294 \ubc18\ub300\ub85c user1@yourhost.domain.org\uac00 user1@freelifemakers.com\uc744 \ud314\ub85c\uc6b0 \ud569\ub2c8\ub2e4.In this [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[27,1,7],"tags":[],"class_list":["post-7987","post","type-post","status-publish","format-standard","hentry","category-nextjs","category-uncategorized","category-website","missing-thumbnail"],"_links":{"self":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/7987","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/comments?post=7987"}],"version-history":[{"count":63,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/7987\/revisions"}],"predecessor-version":[{"id":8055,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/posts\/7987\/revisions\/8055"}],"wp:attachment":[{"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/media?parent=7987"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/categories?post=7987"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.freelifemakers.org\/wordpress\/index.php\/wp-json\/wp\/v2\/tags?post=7987"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}