{"id":15292225,"url":"https://github.com/wp-headless/fetch","last_synced_at":"2026-02-22T02:03:10.897Z","repository":{"id":36284697,"uuid":"223049027","full_name":"wp-headless/fetch","owner":"wp-headless","description":"Isomorphic Wordpress API client and React hooks - super tiny, super fast.","archived":false,"fork":false,"pushed_at":"2023-01-05T01:20:44.000Z","size":2281,"stargazers_count":53,"open_issues_count":33,"forks_count":3,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-10-14T20:13:01.625Z","etag":null,"topics":["api-client","create-react-app","es6","headless","headless-cms","isomorphic","javascript","sdk","wordpress","wordpress-api"],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/wp-headless.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2019-11-20T23:47:58.000Z","updated_at":"2024-05-08T23:13:15.000Z","dependencies_parsed_at":"2023-01-17T01:01:26.261Z","dependency_job_id":null,"html_url":"https://github.com/wp-headless/fetch","commit_stats":null,"previous_names":["wp-fetch/wp-fetch"],"tags_count":28,"template":false,"template_full_name":null,"purl":"pkg:github/wp-headless/fetch","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-headless%2Ffetch","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-headless%2Ffetch/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-headless%2Ffetch/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-headless%2Ffetch/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/wp-headless","download_url":"https://codeload.github.com/wp-headless/fetch/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/wp-headless%2Ffetch/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29703254,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T23:35:04.139Z","status":"online","status_checked_at":"2026-02-22T02:00:08.193Z","response_time":110,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["api-client","create-react-app","es6","headless","headless-cms","isomorphic","javascript","sdk","wordpress","wordpress-api"],"created_at":"2024-09-30T16:17:01.332Z","updated_at":"2026-02-22T02:03:10.874Z","avatar_url":"https://github.com/wp-headless.png","language":"JavaScript","readme":"\u003cp align=\"center\"\u003e\n  \u003cimg src=\"https://beam-wordpress-legacy.s3.ap-southeast-2.amazonaws.com/fetch-k9.png\" width=\"200\" alt=\"wp-headless\"\u003e\n  \u003cbr /\u003e  \u003cbr /\u003e\n  \u003ca href=\"https://cloud.drone.io/wp-headless/fetch\"\u003e\u003cimg src=\"https://cloud.drone.io/api/badges/wp-headless/fetch/status.svg\" alt=\"drone\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://codecov.io/gh/wp-headless/fetch/branch/master\"\u003e\u003cimg src=\"https://img.shields.io/codecov/c/github/wp-headless/fetch/master.svg\" alt=\"Coverage Status\"\u003e\u003c/a\u003e  \n  \u003ca href=\"https://www.npmjs.com/package/@wp-headless/client\"\u003e\u003cimg src=\"https://img.shields.io/npm/v/@wp-headless/client\" alt=\"npm\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://bundlephobia.com/result?p=@wp-headless/client\"\u003e\u003cimg src=\"https://img.shields.io/bundlephobia/minzip/@wp-headless/client\" alt=\"Bundle size\"\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e(Currently in alpha release - use in production at your own risk)\u003c/p\u003e\n\n# Fetch\n\nA Wordpress API client that works both in the browser and in Node. Tiny footprint, \u003e 95% code coverage, [browser tested](https://browserstack.com) down to IE11, tree shakable CJS and ES6 builds, expressive syntax.\n\n- [Why?](#why)\n- [Usage](#usage)\n\n  - Fetch client\n    - [Installation](#installation)\n    - [Resources](#resources)\n    - [HTTP methods](#http-methods)\n    - [Request parameters](#request-parameters)\n    - [Embed data](#embed-data)\n    - [Helper functions](#syntactical-sugar-helper-functions)\n    - [Transport layer](#transport-layers)\n  - Fetch React\n    - Comming soon...\n\n- [Examples](#examples)\n\n## Why?\n\nThere are great alternatives such as [wpapi](https://github.com/WP-API/node-wpapi) and [yllet](https://github.com/ylletjs/yllet) although both of these projects have issues:\n\n- Long unresolved [browser issues](https://github.com/WP-API/node-wpapi/issues/438)\n- Bloated [packages size](https://bundlephobia.com/result?p=wpapi@0.12.1)\n- No [tree-shakable](https://webpack.js.org/guides/tree-shaking/) ESM or CJS build available\n- Opinionated API that attempts to do more then is needed.\n- Lack of automated browser testing and coverage\n\nWe intend to build and support a lean and well tested packages that fit into the modern ES6 javascript ecosystem.\n\n# Client\n\nThe fundamental tool in the `wp-headless` ecosystem is the API client.\n\n## Installation\n\nYarn\n\n```bash\nyarn add @wp-headless/client\n```\n\nNPM\n\n```bash\nnpm install @wp-headless/client\n```\n\n## Usage\n\nCreating a client instance bound to the endpoint of your Wordpress install:\n\n```javascript\nimport Client from '@wp-headless/client';\n\nconst client = new Client('https://demo.wp-api.org/wp-json');\n```\n\nFetching posts:\n\n```javascript\n// post with id 123\nconst post = await client.posts().get(123);\n// post with slug 'hello-world'\nconst post = await client.posts().slug('hello-world');\n// All posts\nconst posts = await client.posts().get();\n// filtered posts\nconst posts = await client.posts().get({\n  per_page: 10,\n  orderby: 'title',\n  search: 'Dog fetches bone'\n});\n```\n\nFetching pages is the same as above, simply change the resource endpoint as follows:\n\n```javascript\n// page with id 456\nconst page = await client.pages().get(456);\n```\n\n### Resources\n\nThe client provides the following API resource methods:\n\n- `client.categories()`\n- `client.comments()`\n- `client.media()`\n- `client.statuses()`\n- `client.posts()`\n- `client.pages()`\n- `client.settings()`\n- `client.tags()`\n- `client.taxonomies()`\n- `client.types()`\n- `client.users()`\n\nThese resource methods are simply syntax sugar for setting the path and namespace to an API resource. Therefore the following are equivalent:\n\n```javascript\nconst posts = await client.posts().get(123);\n```\n\n```javascript\nconst post = await client.get('posts/123');\n```\n\nAdding custom resource methods is easy (example [WooCommerce REST API](https://woocommerce.github.io/woocommerce-rest-api-docs/)), the following would fetch the enpoint http://demo.wp-api.org/wp-json/wc/v2/products:\n\n```javascript\nclient.products = () =\u003e client.namespace('wc/v2').resource('products');\n\nconst products = await client.products().get();\n```\n\nOf course you could simply also do the following:\n\n```javascript\nconst product = await client.namespace('wc/v2').get('products/123');\n```\n\nAs you can see building requests is as simple as setting the `namespace()`, `resource()` and the HTTP method; `get()`, `post()`, `put()`, `patch()` or `delete()`.\n\n### HTTP methods\n\nClient instances also provide access to HTTP methods to access API resources.\n\n```javascript\nclient.get(); // Http GET\nclient.create(); // Http POST\nclient.update(); // Http PATCH\nclient.delete(); // Http DELETE\n```\n\nFor example:\n\n```javascript\n// create a post\nconst post = client.posts().create({\n  title: 'Dog fetches ball',\n  content: '\u003cp\u003ethen he brings it back\u003c/p\u003e'\n});\n// update the post\nconst post = client.posts().update(post.id, {\n  excerpt: 'Its just what dogs do...'\n});\n// delete the post\nclient.posts().delete(post.id);\n```\n\n### Request parameters\n\nYou can pass request parameters as an object to any of the above methods:\n\n```javascript\n// REQUEST URI https://demo.wp-api.org/wp-json/wp/v2/posts\n// REQUEST BODY { title: 'Hello doggy', content: 'fetch a bone' }\nconst post = client.posts().create({\n  title: 'Hello doggy',\n  content: 'fetch a bone'\n});\n```\n\nOr with a get request\n\n```javascript\n// REQUEST URI https://demo.wp-api.org/wp-json/wp/v2/posts?per_page=10\u0026status=draft\nconst post = client.posts().get({\n  per_page: 10,\n  status: 'draft'\n});\n```\n\nIts also possible to set global params that will be sent with each request:\n\n```javascript\n// Sets a single param key/value\nclient.param('per_page', 20);\n\n// Merges an object with current global param values\nclient.param({\n  per_page: 20,\n  orderby: 'title'\n});\n```\n\nTo retrieve global params:\n\n```javascript\n// Single value\nclient.param('source'); // wp-headless\n\n// All values\nclient.params;\n```\n\n### Embed data\n\nWordPress API supports embedding of resources and instead of having to provide `?_embed=true` as a param on every request you can simpley use `embed()` before any request methods.\n\nMore about WordPress API embedding can you read [here](https://developer.wordpress.org/rest-api/using-the-rest-api/linking-and-embedding/#embedding).\n\n```javascript\nconst posts = await client\n  .posts()\n  .embed()\n  .get();\n```\n\nOr globally for all requests:\n\n```javascript\nclient.param('_embed', true);\n\nconst posts = await client.posts().get(); // now embeded\n```\n\n### Syntactical sugar (helper functions)\n\n\u003e Sometimes its helpful to have expressive methods that wrap the underlying api, making code more readable and clean.\n\n`slug(string: slug)`\n\nSlug method is a shortcut to fetch a single post, custom post or page via its `post_name` (slug) attribute.\n\n```javascript\nconst post = client.page().slug('sample-page');\n// ...equivalent to\nconst post = client\n  .page()\n  .get({ slug: 'sample-page', per_page: 1 })\n  .then(posts =\u003e posts[0]);\n```\n\n`more`\n\nWe endevour to add a minimal set of sugar to this library, keeping it small, lean and bloat free is imperative.\n\n## Transport layers\n\nThe architecture of Fetch allows you to specify your own transport layer such as fetch or axios. This allows devs to use a library that they are familiar with, and perhaps are already using in their app, saving bundle size.\n\n### Fetch\n\nThe client uses the [Fetch API Standard](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API) to make requests. This is supported in all modern browsers and newer versions of Node.\n\nTo support older browsers you will have to implement a polyfill such as [isomorphic-fetch](https://github.com/matthew-andrews/isomorphic-fetch) or (isomorphic-unfetch)[https://github.com/developit/unfetch/tree/master/packages/isomorphic-unfetch]:\n\n```bash\nyarn add @wp-headless/client isomorphic-unfetch\n```\n\n```javascript\nimport 'isomorphic-unfetch';\nimport Client from '@wp-headless/client';\n\nconst client = new Client('https://demo.wp-api.org/wp-json');\n```\n\n### Others\n\nIf you would like to use a different transport layer such as `axios` or `superagent` you only need to write an adapter that adheres to interface of the `Transport` class found in the client package. To use this layer pass your custom transport as the second argument to the `Client`:\n\n```javascript\nimport 'isomorphic-unfetch';\nimport Client from '@wp-headless/client';\nimport AxiosTransport from 'my-custom-axios-transport';\n\nconst transport = new AxiosTransport();\n\nconst client = new Client('https://demo.wp-api.org/wp-json', transport);\n```\n\n# React\n\nWe provide (and reccomend) React hooks that take care of your entire darta fetching life cycle. From fetching initial data, caching, optamistic updates, mutating and refetching - its all covered in an incredibly easy to use hook api. Thanks in a large part to [Zeit's swr](https://github.com/zeit/swr)\n\n## Installation\n\nYarn\n\n```bash\nyarn add @wp-headless/react\n```\n\nNPM\n\n```bash\nnpm install @wp-headless/react\n```\n\n## Usage\n\n```javascript\nimport React from 'react';\nimport { usePost } from '@wp-headless/react';\n\nexport const Post = ({ postId }) =\u003e {\n  const { post, fetching } = usePost(postId);\n  return \u003ch1\u003e{post.title.rendered}\u003c/h1\u003e;\n};\n```\n\n## Examples\n\nExamples of usage in a real world application can be found in the `examples` folder.\n\n## Thanks\n\n\u003ca href=\"https://browserstack.com\"\u003e\u003cimg src=\"https://beam-wordpress-legacy.s3-ap-southeast-2.amazonaws.com/Browserstack-logo2.png\" width=\"150\" alt=\"BrowserStack Logo\"\u003e\u003c/a\u003e\n\nThanks to [BrowserStack](https://browserstack.com) for lending us their amazing infrastructure to give us automated browser coverage\n\n\u003ca href=\"https://drone.io\"\u003e\u003cimg src=\"https://beam-wordpress-legacy.s3-ap-southeast-2.amazonaws.com/drone-2.png\" width=\"150\" alt=\"BrowserStack Logo\"\u003e\u003c/a\u003e\n\nThanks to [Drone](https://drone.io/) an incredible pure docker CI/CD platform built on golang for building our stack!\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwp-headless%2Ffetch","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwp-headless%2Ffetch","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwp-headless%2Ffetch/lists"}