FMP

FMP

Enter

stock news

company news

WIX

website creatio

WIX coding

wix developer

developer mode

news fetching

news integratio

financial news

top stock news

top companyNews

Company events

equity news

coding

development

articles api

finance article

news api

stock news api

wix website

How to Fetch Financial News Using the FMP Articles API on Wix: A Step-by-Step Guide

- (Last modified: May 14, 2025 2:38 AM)

twitterlinkedinfacebook
blog post cover photo

Image credit: financial news

If you're looking to add financial news to your Wix website, the Financial Modeling Prep Articles API is a great choice. It provides access to stock market news and updates that can keep your visitors informed. In this guide, I'll walk you through how to connect the FMP Articles API to your Wix site using Wix Velo (Wix's developer mode).
We'll fetch news articles, store them in a Wix database, display them on a news list page, and create individual news pages with unique URLs. I'll explain the code in simple terms, show you how to set it up, and share the results.

What You'll Need Before Starting

  • A Wix account with a site (free or premium).
  • An FMP API key (sign up at financialmodelingprep.com to get one).
  • Basic knowledge of JavaScript (don't worry, I'll keep it simple!).

Step 1: Enable Developer Mode in Wix (Wix Velo)

Wix Velo lets you add custom code to your Wix site, which is perfect for connecting APIs like FMP. Here's how to turn it on:
  • Open Your Wix Editor:
    • Log in to your Wix account and go to your site's dashboard.
    • Click Edit Site to open the Wix Editor.
  • Enable Velo:
    • In the Editor, look at the top menu.
    • Click the Dev Mode icon
    • A sidebar will appear on the left with files like backend, public, and page code.

  • Set Up a Database:
    • On your WIX dashboard Go to CMS > Create Collection.
    • Name it NewsItems.
    • Add fields: title1 (Text), content (Rich Text), image (Image), slug (Text), createdAt (Date and Time), updatedAt (Date and Time).
    • Set permissions: Read: Anyone, Write/Update/Delete: Admin.

  • Store Your API Key:
    • Go to
    • Secrets Manager.
    • Click Add Secret, name it FMP_API_KEY, and paste your FMP API key. Save it.
Now you're ready to write code!

Step 2: Write Backend Code to Fetch News from FMP API

We'll use Wix's backend (server-side) to fetch news from the FMP Articles API, store them in the NewsItems collection, and handle errors. Backend code runs securely and can access your API key.
Create a Backend File
  • In the Wix Editor's Dev Mode sidebar, under Backend, right-click and select New File.
  • Name it news.jsw.

Backend Code (news.jsw)
Here's the code to fetch news and save it to your database:
javascript
import { fetch } from 'wix-fetch';
import wixData from 'wix-data';
import { getSecret } from 'wix-secrets-backend';

// Function to create a URL-friendly slug from the article title
function generateSlug(title) {
  const safeTitle = title || "untitled";
  const stopWords = /\b(the|a|an|and|or|but|in|on|at|to|for|of|with|by)\b/gi;
  return safeTitle
    .toLowerCase()
    .slice(0, 60)
    .replace(stopWords, '')
    .replace(/[^\w\s-]/g, '')
    .replace(/\s+/g, '-')
    .replace(/-+/g, '-')
    .trim();
}

// Main function to fetch and store news
export async function getStockNews() {
  try {
    // Get the API key from Secrets Manager
    const apiKey = await getSecret('FMP_API_KEY');
    if (!apiKey) throw new Error("Missing API key");

    // FMP API endpoint
    const url = `https://financialmodelingprep.com/api/v3/fmp/articles?page=0&size=30&apikey=${apiKey}`;
    const controller = new AbortController();
    const timeoutId = setTimeout(() => controller.abort(), 10000); // 10-second timeout
    const response = await fetch(url, { method: "GET", signal: controller.signal });
    clearTimeout(timeoutId);

    if (!response.ok) throw new Error(`API request failed: ${response.status}`);

    const news = await response.json();
    if (!Array.isArray(news)) throw new Error("News is not an array");

    // Remove duplicates by title
    const seenTitles = new Set();
    const uniqueNews = news.filter(item => {
      if (!item.title || seenTitles.has(item.title)) return false;
      seenTitles.add(item.title);
      return true;
    });

    // Save each news item to the database
    for (const item of uniqueNews) {
      let slug = generateSlug(item.title);
      if (!slug) continue;
      let slugSuffix = 1;
      let uniqueSlug = slug;
      while (true) {
        const existingItem = await wixData.query('NewsItems')
          .eq('slug', uniqueSlug)
          .find();
        if (existingItem.items.length === 0) break;
        uniqueSlug = `${slug}-${slugSuffix}`;
        slugSuffix++;
      }

      const newsItem = {
        title1: item.title || "Untitled",
        content: item.content ? `<p>${item.content.replace(/[\r\n]+/g, '</p><p>')}</p>` : "

No content available

"
, image: item.image || "", slug: uniqueSlug, createdAt: item.date ? new Date(item.date) : new Date(), updatedAt: new Date(), }; const existingItem = await wixData.query('NewsItems') .eq('title1', newsItem.title1) .find(); if (existingItem.items.length > 0) { await wixData.update('NewsItems', { ...newsItem, _id: existingItem.items[0]._id }); } else { await wixData.insert('NewsItems', newsItem); } } // Fetch the latest news items from the database const result = await wixData.query('NewsItems') .descending('createdAt') .limit(30) .find(); const uniqueResults = []; const seenDbTitles = new Set(); for (const item of result.items) { if (!seenDbTitles.has(item.title1)) { uniqueResults.push(item); seenDbTitles.add(item.title1); } } return uniqueResults; } catch (err) { try { const dbItems = await wixData.query('NewsItems') .descending('createdAt') .limit(30) .find(); const uniqueDbItems = []; const seenDbTitles = new Set(); for (const item of dbItems.items) { if (!seenDbTitles.has(item.title1)) { uniqueDbItems.push(item); seenDbTitles.add(item.title1); } } return uniqueDbItems; } catch (dbErr) { throw err; } } } // Function to fetch a single article by slug export async function getNewsBySlug(slug) { try { const result = await wixData.query('NewsItems') .eq('slug', slug) .find(); return result.items.length > 0 ? result.items[0] : null; } catch (err) { throw err; } }

Explanation of the Backend Code

  • Imports: We use wix-fetch to make HTTP requests, wix-data to interact with the database, and wix-secrets-backend to securely access the API key.
  • generateSlug: This function converts an article title (e.g., "Apple's iOS 19 Feature") into a URL-friendly slug (e.g., apples-ios-19-feature). It removes special characters, extra spaces, and common words like "the" or "and".
  • getStockNews:
    • Fetches the API key from Secrets Manager.
    • Calls the FMP API (api/v3/fmp/articles) with a 10-second timeout to avoid hanging.
    • Removes duplicate articles by title using a Set.
    • Generates a unique slug for each article by appending numbers (e.g., -1, -2) if there's a conflict.
    • Saves articles to the NewsItems collection, updating existing ones if they already exist.
    • Returns the latest 30 unique articles from the database, with a fallback to existing items if the API fails.
  • getNewsBySlug: Retrieves a single article by its slug for the full news page.

Step 3: Create the News List Page (Frontend)

Now let's build the news list page to display the articles in a Repeater (a list component in Wix).
Set Up the News List Page
  • Add a Page:
    • In Wix Editor, go to Pages > Add Page > Name it "News" (URL: /news).
  • Add Elements:
    • Add a Repeater (Add (+) > List > Repeater).
    • Set its ID to #repeater1.
    • Inside the repeater, add:
      • #image1 (Image).
      • #textTitle (Text, Montserrat 700, 20px, #333).
      • #textSnippet (Text, Roboto 400, 14px, #333).
      • #linkButton (Button, background #1a73e8, text white).
    • Add a Text element for errors, set ID to #errorMessage (Roboto 400, 16px, #e74c3c, hidden).
    • Wrap everything in a Strip (background #f5f6fa, padding 20px).

Frontend Code (NewsPage.js)
In the Dev Mode sidebar, click on the "NewsPage" page, and add this code:
javascript
import { getStockNews } from 'backend/news.jsw';
import wixLocation from 'wix-location';
import wixStorage from 'wix-storage';

//formatting function stripHtmlTags(html) { return html.replace(/<[^>]*>/g, '').replace(/\s+/g, ' ').trim(); } function generateSlug(title) { const safeTitle = title || "untitled"; const stopWords = /\b(the|a|an|and|or|but|in|on|at|to|for|of|with|by)\b/gi; return safeTitle .toLowerCase() .slice(0, 60) .replace(stopWords, '') .replace(/[^\w\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .trim(); } //Getting Stock News $w.onReady(async function () { try { const news = await getStockNews(); if (!Array.isArray(news) || news.length === 0) { $w("#repeater1").data = []; $w("#repeater1").hide(); if ($w("#errorMessage").length) { $w("#errorMessage").text = "No news available at this time."; $w("#errorMessage").show(); } return; } const seenTitles = new Set(); const uniqueNews = news.filter(item => { if (seenTitles.has(item.title1)) return false; seenTitles.add(item.title1); return true; }); const first9 = uniqueNews.slice(0, 10).map((item, index) => { const slug = item.slug || generateSlug(item.title1); return { ...item, _id: item._id ? item._id.toString() : index.toString(), slug: slug, }; }); //Populating data $w("#repeater1").data = first9; $w("#repeater1").show(); if ($w("#errorMessage").length) { $w("#errorMessage").hide(); } $w("#repeater1").onItemReady(($item, itemData) => { if (itemData.image) { $item("#image1").src = itemData.image; $item("#image1").expand(); } else { $item("#image1").collapse(); } $item("#textTitle").text = itemData.title1 || "No Title"; $item("#textSnippet").text = itemData.content ? stripHtmlTags(itemData.content).slice(0, 120) + "..." : "No snippet available."; $item("#linkButton").label = "Read More"; $item("#linkButton").onClick(() => { if (!itemData.slug) { $item("#textTitle").text = "Error: Missing slug."; return; } try { wixStorage.session.setItem("selectedNews", JSON.stringify(itemData)); wixLocation.to(`/full-news?slug=${itemData.slug}`); } catch (navError) { $item("#textTitle").text = "Error: Navigation failed."; } }); }); } catch (error) { $w("#repeater1").data = []; $w("#repeater1").hide(); if ($w("#errorMessage").length) { $w("#errorMessage").text = "Failed to load news."; $w("#errorMessage").show(); } } });

Explanation of the News List Code

  • Imports: We import getStockNews from the backend, wix-location for navigation, and wix-storage to store data temporarily.
  • stripHtmlTags: Removes HTML tags from the article content to create a short snippet.
  • generateSlug: Matches the backend to ensure consistent slugs.
  • onReady:
    • Calls getStockNews to fetch news.
    • Filters duplicates and limits to 10 items.
    • Sets the repeater data (#repeater1) with each item's image, title, snippet, and a "Read More" button.
    • The button navigates to /full-news?slug= when clicked.
    • Shows an error message if no news items load.

Step 4: Create the Full News Page (Frontend)

This page displays a single news article when the "Read More" button is clicked.
Set Up the Full News Page
  1. Add a Page:
    • Pages > Add Page > Name it "Full News" (URL: /full-news).
  2. Add Elements:
    • #fullTitle (Heading 1, 28px, bold, #333).
    • #fullText (Rich Content, 16px, #333, max-width 800px).
    • #fullImage (Image, max-width 100%, border-radius 8px).
    • #backButton (Button, background #1a73e8, text white).
    • Wrap in Strip (background #f5f6fa, max-width 1000px, padding 20px).
Frontend Code (full-news.js)
Add this code to the "Full News" page:
javascript


Explanation of the Full News Code

Replace PUT_YOUR_WEBSITE_ADRESS with your website and YOUR APP NAME with the name of your app/website

Step 5: Transition to Path-Based URLs

For better SEO, let's switch to path-based URLs (e.g., /full-news/apples-ios-19-feature).
Set Up a Dynamic Page
  • Create Dynamic Page:
    • Pages > Add Page > Dynamic Page.
    • Select NewsItems collection.
    • Set URL to /full-news/{slug} (use slug field).
    • Add the same elements as above.
  • Add Dataset:
    • Add > Dataset.
    • Connect to NewsItems.
    • Filter: slug equals URL parameter slug.
    • Mode: Read.
  • Update Code:
    • news-list.js:
      javascript
      wixLocation.to(`/full-news/${itemData.slug}`);
    • full-news.js:
      javascript
      slugFromUrl = wixLocation.path[1];
      const articleUrl = `https://PUT_YOUR_WEBSITE_ADRESS/full-news/${slugFromUrl}`;

Step 6: Publish and Test

  • Publish Your Site:
    • Click Publish in the Wix Editor.
    • Visit your site.
  • Test:
    • Check the news list page for articles.
    • Click "Read More" to view a full article.
    • Verify the URL (e.g., /full-news/apples-ios-19-feature).
Result of the Code
  • A list of up to 10 news articles with images, titles, and snippets.
  • Each article has a "Read More" button.
  • Clicking "Read More" takes you to the full article page with a unique URL based on the article's title (e.g., /full-news/apples-ios-19-feature).
  • The full news page shows the article title in a 28px bold heading, the content, an image (if available), and a "Back to News" button.
Example:
  • News List Page: Displays articles like "Apple's iOS 19 Feature" with a short snippet and "Read More" button.
  • Full News Page: URL /full-news/apples-ios-19-feature, showing the full article with a bold title and formatted content.
We used Wix's developer mode to write backend and frontend code, store news in a database, and create user-friendly pages with unique URLs. This setup not only adds value to your site but also improves SEO with path-based URLs. Try it out, and happy FMP API integration on Wix!

Other Blogs

Sep 10, 2024 7:33 AM - Parth Sanghvi

Best Alternatives to Yahoo Finance for Downloading Historical Stock Data

When it comes to downloading historical stock data, Yahoo Finance has been a popular choice for many. However, for those looking for more comprehensive, accurate, and flexible options, Financial Modeling Prep (FMP) offers a suite of powerful tools and services that stand out as superior alternatives...

blog post title

Nov 8, 2024 5:30 AM - Sanzhi Kobzhan

Understanding Equity Valuation: When to Use DCF, DDM, and Price-Income (Multiplicators) Models

When it comes to investing in stocks, one of the key decisions an investor must make involves determining the intrinsic value of a company's shares. Equity valuation isn't just about numbers, it's an art mixed with science, aiming to predict future performance based on current and historical data. H...

blog post title

Nov 22, 2024 5:08 AM - Parth Sanghvi

Fundamental Analysis: Principles, Types, and How to Use It

Fundamental analysis is one of the most essential tools for investors and analysts alike, helping them assess the intrinsic value of a stock, company, or even an entire market. It focuses on the financial health and economic position of a company, often using key data such as earnings, expenses, ass...

blog post title
FMP

FMP

Financial Modeling Prep API provides real time stock price, company financial statements, major index prices, stock historical data, forex real time rate and cryptocurrencies. Financial Modeling Prep stock price API is in real time, the company reports can be found in quarter or annual format, and goes back 30 years in history.
twitterlinkedin
2017-2025 © Financial Modeling Prep