> Portal Navigation: > > - Append `.md` to any URL under `https://dev.wix.com/docs/` to get its markdown version. > - Pages are either content pages (article or reference text) or menu pages (a list of links to child pages). > - To get a menu page, truncate any URL to a parent path and append `.md` (e.g. `https://dev.wix.com/docs/sdk.md`, `https://dev.wix.com/docs/sdk/core-modules.md`). > - Top-level index of all portals: https://dev.wix.com/docs/llms.txt > - Full concatenated docs: https://dev.wix.com/docs/llms-full.txt ## Resource: Tutorial | Call External APIs with Fetch ## Article: Tutorial | Call External APIs with Fetch ## Article Link: https://dev.wix.com/docs/develop-websites-sdk/get-started/tutorials/integrations/tutorial-call-external-apis-with-fetch.md ## Article Content: # Tutorial | Call External APIs with Fetch In this tutorial, you'll learn how to use the fetch API to connect to an external service and display data items retrieved from that service. Site visitors can click a button to fetch and display a collection of greetings in different languages. > **Note:** To see this example in action, see [Hello Fetch](https://dev.wix.com/docs/coding-examples/getting-started/hello-world/hello-fetch.md). By the end of this tutorial, you'll have a working example that fetches greetings data from an external API and displays it on your site using a repeater element. ![Fetch many example](https://wixmp-833713b177cebf373f611808.wixmp.com/images/4789c3978a0be343919ee225b9083e6d.png) ## Step 1 | Add elements to your page Add the following elements to your page: - A [button](https://dev.wix.com/docs/velo/velo-only-apis/$w/button/introduction.md) to fetch the greetings. Set the button ID to `fetchGreetingsButton`. - A [repeater](https://dev.wix.com/docs/velo/velo-only-apis/$w/repeater/introduction.md) to display multiple data items. Set the repeater ID to `greetingsRepeater`. - A [text](https://dev.wix.com/docs/velo/velo-only-apis/$w/text/introduction.md) element to display the greeting's language inside the repeater. Set the text element ID to `repeatedLanguage`. - A text element to display the greeting inside the repeater. Set the text element ID to `repeatedGreeting`. ## Step 2 | Add backend code Create a new [web module](https://dev.wix.com/docs/develop-websites-sdk/code-your-site/build-a-custom-backend/web-modules/about-web-modules.md) file called `dataFetcher.web.js` and add the following code to fetch greetings from an external API: ```javascript import { webMethod, Permissions } from "wix-web-module"; export const getGreetings = webMethod(Permissions.Anyone, async () => { try { const response = await fetch( "https://velo-examples.wixstudio.com/examples-backends/_functions/greetings" ); const json = await response.json(); return json; } catch (error) { return { error: "Failed to fetch greetings." }; } }); ``` ## Step 3 | Add frontend code In the code for the page where you added the elements above: 1. Add the import statement, hide the repeater, and set up a button click event handler: ```javascript import { getGreetings } from "backend/dataFetcher.web.js"; $w.onReady(function () { $w("#greetingsRepeater").hide(); $w("#fetchGreetingsButton").onClick(async () => { // Button click logic will go here }); }); ``` 1. Disable the button during fetch to prevent multiple clicks: ```javascript $w("#fetchGreetingsButton").disable(); ``` 1. Call the backend function to retrieve the greetings data: ```javascript const fetchedData = await getGreetings(); ``` 1. Transform the data by adding `_id` properties, as required by repeater elements: ```javascript const repeaterData = fetchedData.map((item) => { item._id = item.id.toString(); return item; }); ``` 1. Populate the repeater with the transformed data: ```javascript $w("#greetingsRepeater").data = repeaterData; ``` 1. Make the previously hidden repeater visible: ```javascript $w("#greetingsRepeater").show(); ``` 1. Change the button label to indicate completion: ```javascript $w("#fetchGreetingsButton").label = "Done"; ``` This completes the code requirements within the `onReady` function. 1. In a new code block, set up how each item in the repeater displays its data: ```javascript $w("#greetingsRepeater").onItemReady(($item, itemData) => { $item("#repeatedLanguage").text = itemData.language; $item("#repeatedGreeting").text = itemData.greeting; }); ``` ## Complete code example ### Backend ```javascript // In the dataFetcher.web.js file import { webMethod, Permissions } from "wix-web-module"; export const getGreetings = webMethod(Permissions.Anyone, async () => { try { const response = await fetch( "https://velo-examples.wixstudio.com/examples-backends/_functions/greetings" ); const json = await response.json(); return json; } catch (error) { return { error: "Failed to fetch greetings." }; } }); ``` ### Frontend ```javascript import { getGreetings } from "backend/dataFetcher.web.js"; $w.onReady(function () { $w("#greetingsRepeater").hide(); $w("#fetchGreetingsButton").onClick(async () => { $w("#fetchGreetingsButton").disable(); const fetchedData = await getGreetings(); const repeaterData = fetchedData.map((item) => { item._id = item.id.toString(); return item; }); $w("#greetingsRepeater").data = repeaterData; $w("#greetingsRepeater").show(); $w("#fetchGreetingsButton").label = "Done"; }); $w("#greetingsRepeater").onItemReady(($item, itemData) => { $item("#repeatedLanguage").text = itemData.language; $item("#repeatedGreeting").text = itemData.greeting; }); }); ``` ## See also - [Web Methods API](https://dev.wix.com/docs/sdk/core-modules/web-methods/introduction.md) - [The Lifecycle of Repeated Items](https://dev.wix.com/docs/velo/velo-only-apis/$w/repeater/the-lifecycle-of-repeated-items.md)