<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: lokprakash babu</title>
    <description>The latest articles on DEV Community by lokprakash babu (@rookiecoder).</description>
    <link>https://dev.to/rookiecoder</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F1098792%2Ff7e7f559-ae40-4d90-ac07-85689131928e.png</url>
      <title>DEV Community: lokprakash babu</title>
      <link>https://dev.to/rookiecoder</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/rookiecoder"/>
    <language>en</language>
    <item>
      <title>🦜 Meet Parrot: The Slack App That Talks Like You Want To</title>
      <dc:creator>lokprakash babu</dc:creator>
      <pubDate>Sun, 04 May 2025 16:51:57 +0000</pubDate>
      <link>https://dev.to/rookiecoder/meet-parrot-the-slack-app-that-talks-like-you-want-to-3hic</link>
      <guid>https://dev.to/rookiecoder/meet-parrot-the-slack-app-that-talks-like-you-want-to-3hic</guid>
      <description>&lt;p&gt;&lt;a href="https://dev.tourl"&gt;&lt;/a&gt;&lt;em&gt;This is a submission for the &lt;a href="https://dev.to/challenges/aws-amazon-q-v2025-04-30"&gt;Amazon Q Developer "Quack The Code" Challenge&lt;/a&gt;: Exploring the Possibilities&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  What I Built
&lt;/h2&gt;

&lt;p&gt;In the middle of a long workday, how many times have you written a Slack message, paused, and thought:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Hmm… that sounds too harsh. Should I rewrite that?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;“Can this be clearer? Simpler? More polite?”&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now you don’t have to second guess.&lt;br&gt;
Just summon Parrot, and it rephrases your message in the tone you need — with a single Slack command.&lt;/p&gt;
&lt;h2&gt;
  
  
  🧠 What is Parrot?
&lt;/h2&gt;

&lt;p&gt;Parrot is a Slack app that transforms your raw, rushed, or robotic messages into something more human — with improved politeness, clarity, or simplicity.&lt;/p&gt;

&lt;p&gt;You just type:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;/polite Can you do this now?&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And Parrot replies:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Would you be able to do this when you get a chance?"&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Or:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;/clarity Let’s sync up sometime soon.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;And Parrot says:&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;"Let’s schedule a quick meeting this week to align."&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;It’s like Grammarly — but instant, and inside Slack. &lt;/p&gt;
&lt;h2&gt;
  
  
  Demo
&lt;/h2&gt;

&lt;p&gt;  &lt;iframe src="https://www.youtube.com/embed/oR3OBtNIUWc"&gt;
  &lt;/iframe&gt;
&lt;/p&gt;

&lt;h2&gt;
  
  
  How I Used Amazon Q Developer
&lt;/h2&gt;

&lt;p&gt;I didn’t code this project alone.&lt;br&gt;
I built Parrot with a little help from my AI pair programmer — Amazon Q.&lt;/p&gt;

&lt;p&gt;Instead of Googling every edge case, manually wiring Express routes, or debugging bash scripts — I asked Amazon Q Developer to build with me.&lt;/p&gt;

&lt;p&gt;Here’s how:&lt;/p&gt;
&lt;h3&gt;
  
  
  💻 Amazon Q Helped Me Code Smarter
&lt;/h3&gt;

&lt;p&gt;I used Amazon Q to generate core parts of the app:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;The Express.js server&lt;/li&gt;
&lt;li&gt;The three distinct Slack command routes&lt;/li&gt;
&lt;li&gt;The Bedrock API integration to connect to Claude (for language generation)&lt;/li&gt;
&lt;li&gt;Validation logic, error handlers, and .env setup&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Rather than write from scratch, I wrote a prompt:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;"Build an Express app that responds to 3 different Slack slash commands and calls Bedrock to rephrase text."
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;Boom. Code. Working. Editable. In seconds.&lt;/p&gt;
&lt;h2&gt;
  
  
  🚀 Amazon Q Helped Me Deploy Faster
&lt;/h2&gt;

&lt;p&gt;I didn’t stop at coding. I asked Amazon Q:&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;“Write a shell script to SSH into my EC2 instance, pull the latest code, and restart the server using PM2.”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;It gave me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;A full deploy.sh script&lt;/li&gt;
&lt;li&gt;Instructions on how to manage the app with PM2, including log viewing and restart-on-crash support&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Amazon Q became my DevOps intern. Minus the coffee breaks. 😀&lt;/p&gt;
&lt;h2&gt;
  
  
  🌐 Live on EC2
&lt;/h2&gt;

&lt;p&gt;Parrot is running 24/7 on an AWS EC2 instance, deployed via SSH, managed with PM2.&lt;/p&gt;

&lt;p&gt;It’s one of those small tools that makes team communication better every single day.&lt;/p&gt;
&lt;h2&gt;
  
  
  🤖 The Bigger Picture: AI That Enables Creation
&lt;/h2&gt;

&lt;p&gt;This wasn’t about using AI to be the product.&lt;br&gt;
This was about using AI to build the product.&lt;/p&gt;

&lt;p&gt;Amazon Q helped me:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Write production code&lt;/li&gt;
&lt;li&gt;Avoid repetitive work&lt;/li&gt;
&lt;li&gt;Learn while building&lt;/li&gt;
&lt;li&gt;Focus on value, not syntax&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;It felt like having another developer on-call, at every step.&lt;/p&gt;
&lt;h2&gt;
  
  
  🎯 Why Parrot Matters
&lt;/h2&gt;

&lt;ol&gt;
&lt;li&gt;Teams waste hours rewording messages. Parrot does it instantly.&lt;/li&gt;
&lt;li&gt;Tone is everything in remote work. Parrot helps you get it right.&lt;/li&gt;
&lt;li&gt;AI can be useful in micro-moments. Parrot makes that real.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2&gt;
  
  
  🙏 Thanks to Amazon Q
&lt;/h2&gt;

&lt;p&gt;Thanks to the Amazon Q Developer CLI, I went from idea → app → deploy in a fraction of the time — and learned a ton doing it.&lt;/p&gt;
&lt;h2&gt;
  
  
  💬 Final Words
&lt;/h2&gt;

&lt;p&gt;This isn’t just an AI-generated app.&lt;br&gt;
This is a human idea, built faster with machine intelligence.&lt;/p&gt;

&lt;p&gt;Parrot didn’t just repeat what I said.&lt;br&gt;
It rephrased how I want to say.&lt;/p&gt;
&lt;h2&gt;
  
  
  Code Repository
&lt;/h2&gt;


&lt;div class="ltag-github-readme-tag"&gt;
  &lt;div class="readme-overview"&gt;
    &lt;h2&gt;
      &lt;img src="https://assets.dev.to/assets/github-logo-5a155e1f9a670af7944dd5e12375bc76ed542ea80224905ecaf878b9157cdefc.svg" alt="GitHub logo"&gt;
      &lt;a href="https://github.com/Lokprakash-babu" rel="noopener noreferrer"&gt;
        Lokprakash-babu
      &lt;/a&gt; / &lt;a href="https://github.com/Lokprakash-babu/parrot" rel="noopener noreferrer"&gt;
        parrot
      &lt;/a&gt;
    &lt;/h2&gt;
    &lt;h3&gt;
      
    &lt;/h3&gt;
  &lt;/div&gt;
  &lt;div class="ltag-github-body"&gt;
    
&lt;div id="readme" class="md"&gt;
&lt;div class="markdown-heading"&gt;
&lt;h1 class="heading-element"&gt;Parrot - Message Rephrasing Slack Bot with AWS Bedrock&lt;/h1&gt;
&lt;/div&gt;
&lt;p&gt;This is a Slack bot that rephrases messages using AWS Bedrock's AI models to improve tone, clarity, or simplicity.&lt;/p&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Features&lt;/h2&gt;
&lt;/div&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Slash commands for different rephrasing styles:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;/polite&lt;/code&gt; - Makes messages more polite and professional&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/clarity&lt;/code&gt; - Improves clarity and readability&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;/simple&lt;/code&gt; - Simplifies complex messages&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Powered by AWS Bedrock AI models:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Claude (Anthropic)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="markdown-heading"&gt;
&lt;h2 class="heading-element"&gt;Setup&lt;/h2&gt;
&lt;/div&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Prerequisites&lt;/h3&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;AWS Account with access to AWS Bedrock&lt;/li&gt;
&lt;li&gt;Node.js and npm/yarn installed&lt;/li&gt;
&lt;li&gt;Slack workspace with permission to add apps&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;AWS Bedrock Setup&lt;/h3&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Enable AWS Bedrock in your AWS account&lt;/li&gt;
&lt;li&gt;Request access to the models you want to use (Claude)&lt;/li&gt;
&lt;li&gt;Set up AWS credentials on your machine or deployment environment&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Installation&lt;/h3&gt;

&lt;/div&gt;
&lt;ol&gt;
&lt;li&gt;Clone this repository&lt;/li&gt;
&lt;li&gt;Install dependencies:
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;npm install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
or
&lt;div class="snippet-clipboard-content notranslate position-relative overflow-auto"&gt;&lt;pre class="notranslate"&gt;&lt;code&gt;yarn install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;div class="markdown-heading"&gt;
&lt;h3 class="heading-element"&gt;Configuration&lt;/h3&gt;

&lt;/div&gt;
&lt;p&gt;Set the following environment variables:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;AWS_REGION&lt;/code&gt;: AWS region where Bedrock is available (default: "us-east-1")&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AWS_ACCESS_KEY_ID&lt;/code&gt;: Your AWS access key&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;AWS_SECRET_ACCESS_KEY&lt;/code&gt;: Your AWS secret…&lt;/li&gt;
&lt;/ul&gt;
&lt;/div&gt;
  &lt;/div&gt;
  &lt;div class="gh-btn-container"&gt;&lt;a class="gh-btn" href="https://github.com/Lokprakash-babu/parrot" rel="noopener noreferrer"&gt;View on GitHub&lt;/a&gt;&lt;/div&gt;
&lt;/div&gt;


</description>
      <category>devchallenge</category>
      <category>awschallenge</category>
      <category>ai</category>
      <category>webdev</category>
    </item>
    <item>
      <title>On-demand revalidation ⚡️</title>
      <dc:creator>lokprakash babu</dc:creator>
      <pubDate>Sun, 11 Jun 2023 13:13:42 +0000</pubDate>
      <link>https://dev.to/rookiecoder/on-demand-revalidation-1b1e</link>
      <guid>https://dev.to/rookiecoder/on-demand-revalidation-1b1e</guid>
      <description>&lt;h2&gt;
  
  
  Table of Contents
&lt;/h2&gt;

&lt;p&gt; 1. Introduction:&lt;br&gt;
 2. What is On-demand validation and how it works:&lt;br&gt;
 3. Setup:&lt;br&gt;
 4. A Catch&lt;br&gt;
 5. Conclusion&lt;br&gt;
 6. References&lt;/p&gt;
&lt;h2&gt;
  
  
  Introduction:
&lt;/h2&gt;

&lt;p&gt;When a blog page or a product landing page is created, we prefer them to be static pages. Because, it is less likely to have a dynamic content or complex interactions on them. In an organisation, it is not scalable to have a developer involvement for publishing each marketing page or blog page. Hence, it is logical to off board the publishing process from developer to the respective teams which are managing the content. &lt;/p&gt;

&lt;p&gt;This leads to separation of content rendering and content publishing process. The ideal flow would be, when a team publishes a content(in a certain tool), the content should reflect in the desired target(website maybe) without any developer involvement. &lt;/p&gt;

&lt;p&gt;In this blog, we will discuss on how to achieve the above mentioned functionality using a headless CMS, Next JS and Vercel's infrastructure. &lt;/p&gt;
&lt;h2&gt;
  
  
  What is On-demand validation and how it works:
&lt;/h2&gt;

&lt;p&gt;When a static website is deployed to Vercel, the page is actually served from Vercel's CDN, it is also called as 'edge network'. Edge network lies near to a consumer region to serve a swiftly. When a deployment happens the CDN's cache will be invalidated. Hence, when a request comes to a CDN, the page request will be served from Vercel's server and the new page will be stored in CDN's Cache. &lt;/p&gt;

&lt;p&gt;There can be an use-case where a page might have to refresh its content in a periodic time interval. To support this &lt;strong&gt;Incremental static regeneration&lt;/strong&gt; is available.&lt;/p&gt;

&lt;p&gt;However, there can also be certain use cases, where a page doesn't have to refresh its content in an interval, but, it should reflect a new/updated content whenever a new data is added, deleted or updated in a CMS. &lt;strong&gt;On-demand validation&lt;/strong&gt; will help us solve this. &lt;/p&gt;

&lt;p&gt;When an operation is performed on a content in a CMS, we will make use of &lt;code&gt;revalidate&lt;/code&gt; api from the NEXT JS, to invalidate a cache in the Edge CDN, which in-turns refresh a respective page. Basically, it is imitating a deployment for a particular page. &lt;/p&gt;
&lt;h2&gt;
  
  
  Setup:
&lt;/h2&gt;

&lt;p&gt;We are going to use Strapi and Next JS(Page router) in this blog post to create a blog listing page.&lt;/p&gt;

&lt;p&gt;Create a Next app with page router configuration &lt;br&gt;
&lt;code&gt;npx create-next-app@latest&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Create a strapi project &lt;code&gt;yarn create strapi-app my-blogs-strapi&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Before proceeding to our Next JS project, let's finish our Strapi part. &lt;/p&gt;

&lt;p&gt;In Strapi, we will create a content type which represents how a blog post looks like. Once, a content type is defined, an author can publish a content corresponding to a content type using content manager.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgkzg4ng7i0uwiyispsd.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbgkzg4ng7i0uwiyispsd.png" alt="Content Type and Content Manager" width="800" height="884"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;For the scope of this blog post, let's create a content type called &lt;code&gt;blog&lt;/code&gt; which has &lt;code&gt;blogTitle&lt;/code&gt; and &lt;code&gt;blogDescription&lt;/code&gt; fields. &lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11ive9qroh3pnne83ewh.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F11ive9qroh3pnne83ewh.png" alt="Content type - blog" width="800" height="406"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;After creating a content type, we will create Webhook for CRUD(Create, Read, Update and Delete) operations. &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqdioxt83ylj4u0ep6x0b.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fqdioxt83ylj4u0ep6x0b.png" alt="Webhook creation" width="800" height="357"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To create a Webhook, an endpoint for making a post request by Strapi when there are any operation performed on a content type, needs to be created. We will use Next JS api route to create the endpoint.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk22k0rz7gqbfnz4x2rwg.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fk22k0rz7gqbfnz4x2rwg.png" alt="Webhook creation" width="800" height="550"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Let's create a file named &lt;code&gt;revalidate.js&lt;/code&gt; inside the api folder. The path for revalidation will be &lt;code&gt;/api/revalidate&lt;/code&gt;. A POST request with a request body will be made to this endpoint by Strapi.&lt;/p&gt;

&lt;p&gt;The request body associated from strapi has three main attributes, &lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;entry&lt;/li&gt;
&lt;li&gt;model&lt;/li&gt;
&lt;li&gt;event&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;code&gt;event&lt;/code&gt;: Describes whether a content is created, updated, published or unpublished. &lt;/p&gt;

&lt;p&gt;&lt;code&gt;model&lt;/code&gt;: Represents a content type. In this case, it is &lt;code&gt;blog&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;entry&lt;/code&gt;: Represents the entry on which an action is performed from content manager.&lt;/p&gt;

&lt;p&gt;Sample payloads can be referred from the codeblocks.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  event: 'entry.create',
  createdAt: '2023-06-11T11:42:51.225Z',
  model: 'blog',
  uid: 'api::blog.blog',
  entry: {
    id: 1,
    blogTitle: 'Blog 1',
    blogDescription: 'Blog description 1',
    createdAt: '2023-06-11T11:42:51.220Z',
    updatedAt: '2023-06-11T11:42:51.220Z',
    publishedAt: null
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  event: 'entry.update',
  createdAt: '2023-06-11T11:42:54.458Z',
  model: 'blog',
  uid: 'api::blog.blog',
  entry: {
    id: 1,
    blogTitle: 'Blog 1',
    blogDescription: 'Blog description 1',
    createdAt: '2023-06-11T11:42:51.220Z',
    updatedAt: '2023-06-11T11:42:54.456Z',
    publishedAt: '2023-06-11T11:42:54.455Z'
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;





&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;{
  event: 'entry.publish',
  createdAt: '2023-06-11T11:42:54.458Z',
  model: 'blog',
  entry: {
    id: 1,
    blogTitle: 'Blog 1',
    blogDescription: 'Blog description 1',
    createdAt: '2023-06-11T11:42:51.220Z',
    updatedAt: '2023-06-11T11:42:54.456Z',
    publishedAt: '2023-06-11T11:42:54.455Z'
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;However, we are interested in the attributes event and model. Because, event informs us what happened to a content type, and model describes what content-type got updated. Although, these attributes solves for the scope of this blog, if we have to revalidate a specific page, like blog details page, &lt;code&gt;entry&lt;/code&gt; attribute will be useful. Without model, it might not be possible to know which page to be revalidated. For example, if a model is blog and a blog listing page is available, then, whenever an action is performed on the blog content type we have to revalidate the blog listing page.&lt;/p&gt;

&lt;p&gt;Sample code for &lt;code&gt;revalidate.js&lt;/code&gt;&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;const modelToPageMap = {
  blog: "/blogs",
};

export default async function handler(req, res) {
  const requestMethod = req.method;
  if (requestMethod === "POST") {
    const requestBody = req.body;
    const model = requestBody.model;
    await res.revalidate(modelToPageMap[model]);
    return res.json({ revalidated: true });
  } else {
    return res.status(405).json({
      text: "Method not supported",
    });
  }
}
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h2&gt;
  
  
  A Catch
&lt;/h2&gt;

&lt;p&gt;We are passing a path to revalidate api. There are chances where a path doesn't exist. For example, when we create a new blog, the api will revalidate with /blog/[new-blog-url]. However, this path doesn't exist. Hence, revalidation will fail. In order to handle this scenario, a good practise is to pair getStaticPaths and getStaticProps. Instead of returning 404 for not found paths, if a fallback &lt;code&gt;true&lt;/code&gt; is returned, a loader screen can be shown while the getStaticProps fetches a particular page's data. If the data is not available, we can redirect to 404 or handle in a customisable manner. Once the new page is constructed, revalidation can be performed when an update or un-publish action occur.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusion
&lt;/h2&gt;

&lt;p&gt;On-demand revalidation helps us optimizing the number of revalidation performed when a page is Incremental Static Regenerated. Most of the matured CMS will have webhook to implement this functionality. For the purpose of this blog, the endpoint for webhook is given in localhost. For production-ready it needs to be replaced with an actual https endpoint. &lt;/p&gt;

&lt;h2&gt;
  
  
  References
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://docs.strapi.io/dev-docs/installation/cli" rel="noopener noreferrer"&gt;Strapi Installation&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://nextjs.org/docs/pages/building-your-application/rendering/incremental-static-regeneration" rel="noopener noreferrer"&gt;On demand revalidation&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>webdev</category>
      <category>javascript</category>
      <category>nextjs</category>
      <category>strapi</category>
    </item>
  </channel>
</rss>
