DEV Community

Kiran Krishnan
Kiran Krishnan

Posted on • Edited on • Originally published at kirandev.com

How to Build a Custom Raycast Extension to Access Dev.to Articles

In this tutorial, we will build a custom Raycast extension that fetches the latest articles from Dev.to and displays them in a list and opens the selected article in the browser.

Visit the Raycast Doc to learn more about the system requirements you need to start building extensions.

Create a new extension

  • Open the Create Extension command in Raycast
  • Choose the Template Static List
  • Name your extension Devto Articles
  • Name the command Latest Articles
  • Click Create Extension from the bottom right corner

This will create a new directory called devto-articles in your extensions directory.

Install the dependencies

Now, let's dive into the code.

Open the extension directory devto-articles in your favorite code editor.

Install the dependencies by running the following command:

npm install
Enter fullscreen mode Exit fullscreen mode

Before continuing, let's install the @raycast/api package. It contains a set of components that make it easier to build extensions.

npm install @raycast/utils
Enter fullscreen mode Exit fullscreen mode

Build the extension

Now we are ready to start building the extension.

Open the src/index.tsx file, this is where we will write the code that fetches the latest articles from Dev.to and displays them in a list.

Remove the existing code from the src/index.tsx so that we can start from scratch.

Now, let's import the useFetch hook from @raycast/utils. useFetch can be used to fetch data from an API.

import { ActionPanel, Action, List } from "@raycast/api";
import { useFetch } from "@raycast/utils";
Enter fullscreen mode Exit fullscreen mode

Define the type of the article object to map the response from the API.

type Article = {
  id: number;
  title: string;
  readable_publish_date: string;
  comments_count: number;
  url: string;
};
Enter fullscreen mode Exit fullscreen mode

Now, let's use the useFetch hook to fetch the latest articles from Dev.to.

export default function Command() {
  const { isLoading, data: articles } = useFetch<Article[]>(
    "https://dev.to/api/articles"
  );
}
Enter fullscreen mode Exit fullscreen mode

useFetch returns an object with two properties: isLoading and data.

  • isLoading is a boolean that indicates whether the data is being fetched or not.
  • data is the response that is fetched from the API.

Now, let's use the List component to display the articles in a list.

return (
  <List isLoading={isLoading}>
    {(articles || []).map((article) => (
      <List.Item
        key={article.id}
        icon="list-icon.png"
        title={article.title}
        subtitle={`${article.comments_count} comments`}
        accessories={[{ text: article.readable_publish_date }]}
        actions={
          <ActionPanel>
            <Action.OpenInBrowser url={article.url} />
          </ActionPanel>
        }
      />
    ))}
  </List>
);
Enter fullscreen mode Exit fullscreen mode

The List component takes an isLoading prop that indicates whether the data is being fetched or not.

It also takes a children prop that is an array of List.Item components.

The ActionPanel is a component that contains a set of actions that can be performed on the selected item.

In our case, we want to open the selected article in the browser. So, we will use the Action.OpenInBrowser component to open the article in the browser when the user selects it.

Here is the final code:

import { ActionPanel, Action, List } from "@raycast/api";
import { useFetch } from "@raycast/utils";

type Article = {
  id: number;
  title: string;
  readable_publish_date: string;
  comments_count: number;
  url: string;
};

export default function Command() {
  const { isLoading, data: articles } = useFetch<Article[]>(
    "https://dev.to/api/articles"
  );

  return (
    <List isLoading={isLoading}>
      {(articles || []).map((article) => (
        <List.Item
          key={article.id}
          icon="list-icon.png"
          title={article.title}
          subtitle={`${article.comments_count} comments`}
          accessories={[{ text: article.readable_publish_date }]}
          actions={
            <ActionPanel>
              <Action.OpenInBrowser url={article.url} />
            </ActionPanel>
          }
        />
      ))}
    </List>
  );
}
Enter fullscreen mode Exit fullscreen mode

Run the extension

You can run the extension by running the following command:

npm run dev
Enter fullscreen mode Exit fullscreen mode

Find the extension in Raycast by searching for Devto Articles and run the command Latest Articles.

Top comments (0)