<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[Prasad's Notes]]></title><description><![CDATA[Prasad's Notes]]></description><link>https://blog.prasadgaikwad.dev</link><image><url>https://cdn.hashnode.com/res/hashnode/image/upload/v1609625549390/L3VcUm0B0.png</url><title>Prasad&apos;s Notes</title><link>https://blog.prasadgaikwad.dev</link></image><generator>RSS for Node</generator><lastBuildDate>Thu, 16 Apr 2026 19:34:24 GMT</lastBuildDate><atom:link href="https://blog.prasadgaikwad.dev/rss.xml" rel="self" type="application/rss+xml"/><language><![CDATA[en]]></language><ttl>60</ttl><item><title><![CDATA[Supercharge Spring Data JPA: Dynamic Filtering & Performance Optimization with Slices]]></title><description><![CDATA[Building efficient search APIs in Spring Boot often leads to two common problems: infinite boilerplate code for dynamic filtering and performance bottlenecks caused by unnecessary count queries.
In this post, I'll share how we solved both using a Gen...]]></description><link>https://blog.prasadgaikwad.dev/supercharge-spring-data-jpa-dynamic-filtering-and-performance-optimization-with-slices</link><guid isPermaLink="true">https://blog.prasadgaikwad.dev/supercharge-spring-data-jpa-dynamic-filtering-and-performance-optimization-with-slices</guid><category><![CDATA[Spring]]></category><category><![CDATA[Spring Data Jpa]]></category><dc:creator><![CDATA[Prasad Gaikwad]]></dc:creator><pubDate>Sun, 08 Feb 2026 23:12:18 GMT</pubDate><content:encoded><![CDATA[<p>Building efficient search APIs in Spring Boot often leads to two common problems: infinite boilerplate code for dynamic filtering and performance bottlenecks caused by unnecessary count queries.</p>
<p>In this post, I'll share how we solved both using a <strong>Generic Specification Repository</strong> and <strong>Slice-based Pagination</strong>.</p>
<h2 id="heading-1-the-problem-boilerplate-amp-heavy-queries"><strong>1. The Problem: Boilerplate &amp; Heavy Queries</strong></h2>
<h3 id="heading-the-boilerplate-trap"><strong>The Boilerplate Trap</strong></h3>
<p>Typically, allowing users to filter by <code>name</code>, <code>status</code>, <code>createdDate</code>, etc., requires writing endless custom repository methods or complex <code>CriteriaBuilder</code> logic.</p>
<h3 id="heading-the-count-query-killer"><strong>The Count Query Killer</strong></h3>
<p>Standard pagination (<code>Page&lt;T&gt;</code>) executing <code>findAll(Pageable)</code> triggers two queries:</p>
<ol>
<li><p>The actual data query (<code>SELECT ... LIMIT ? OFFSET ?</code>).</p>
</li>
<li><p>A total count query (<code>SELECT COUNT(*) ...</code>).</p>
</li>
</ol>
<p>For large tables, <strong>the count query is a performance killer</strong>. If you're building an "Infinite Scroll" or "Load More" feature, you don't even <em>need</em> the total count—you just need to know if there's a "next page".</p>
<hr />
<h2 id="heading-2-the-solution-generic-specification-repository"><strong>2. The Solution: Generic Specification Repository</strong></h2>
<p>We implemented a wrapper around <code>JpaSpecificationExecutor</code> that accepts a dynamic <code>SearchRequest</code>. This allows us to filter <strong>any entity</strong> without writing custom query code.</p>
<h3 id="heading-the-interface"><strong>The Interface</strong></h3>
<pre><code class="lang-java"><span class="hljs-meta">@NoRepositoryBean</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">SpecificationRepository</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">ID</span>&gt; <span class="hljs-keyword">extends</span> <span class="hljs-title">JpaRepository</span>&lt;<span class="hljs-title">T</span>, <span class="hljs-title">ID</span>&gt;, <span class="hljs-title">SliceSpecificationExecutor</span>&lt;<span class="hljs-title">T</span>&gt; </span>{    
    <span class="hljs-comment">// Inherits findAll(Specification&lt;T&gt;, Pageable)    </span>
    <span class="hljs-comment">// Inherits findAllSliced(Specification&lt;T&gt;, Pageable)</span>
}
</code></pre>
<h3 id="heading-the-usage"><strong>The Usage</strong></h3>
<p>Now, any repository can extend this and instantly gain dynamic search powers:</p>
<pre><code class="lang-java"><span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">interface</span> <span class="hljs-title">ThreatActorRepository</span> <span class="hljs-keyword">extends</span> <span class="hljs-title">SpecificationRepository</span>&lt;<span class="hljs-title">ThreatActor</span>, <span class="hljs-title">UUID</span>&gt; </span>{}
</code></pre>
<p>The Service layer simply builds the specification from a JSON request:</p>
<pre><code class="lang-java"><span class="hljs-function"><span class="hljs-keyword">public</span> Page&lt;ThreatActor&gt; <span class="hljs-title">search</span><span class="hljs-params">(SearchRequest request)</span> </span>{    
    Specification&lt;ThreatActor&gt; spec = GenericSpecificationBuilder.buildFromRequest(request);    
    <span class="hljs-keyword">return</span> repository.findAll(spec, pageable);
}
</code></pre>
<hr />
<h2 id="heading-3-the-optimization-slice-vs-page"><strong>3. The Optimization: Slice vs. Page</strong></h2>
<p>To solve the count query performance issue, we implemented <code>SliceSpecificationExecutor</code>.</p>
<h3 id="heading-what-is-a-slice"><strong>What is a Slice?</strong></h3>
<p>A <code>Slice</code> in Spring Data holds a chunk of data and knows if there is a next slice (<code>hasNext()</code>), but it <strong>does not</strong> know the total number of pages.</p>
<h3 id="heading-implementing-findallsliced"><strong>Implementing</strong> <code>findAllSliced</code></h3>
<p>We leveraged Spring Data's <code>Window</code> API (introduced recently) to fetch results efficiently:</p>
<pre><code class="lang-java">SliceSpecificationExecutor.<span class="hljs-function">javadefault Slice&lt;T&gt; <span class="hljs-title">findAllSliced</span><span class="hljs-params">(Specification&lt;T&gt; spec, Pageable pageable)</span> </span>{    <span class="hljs-comment">// Uses a "Window" to fetch size + 1 items to determine if a next page exists    // completely avoiding the SELECT COUNT(*) query.    Window&lt;T&gt; window = this.findBy(spec, ...);    return new SliceImpl&lt;&gt;(window.getContent(), pageable, window.hasNext());}</span>
</code></pre>
<h3 id="heading-the-performance-win"><strong>The Performance Win</strong></h3>
<p>By switching from <code>/search</code> (Page) to <code>/search-sliced</code> (Slice), we eliminate the heavy count query entirely.</p>
<p><strong>SQL Comparison:</strong></p>
<p><strong>Regular Page Request:</strong></p>
<pre><code class="lang-bash">sqlHibernate: select ... from threat_actors <span class="hljs-built_in">limit</span> ? offset ?Hibernate: select count(*) from threat_actors ... -- 🛑 EXPENSIVE on large tables
</code></pre>
<p><strong>Slice Request:</strong></p>
<pre><code class="lang-bash">sqlHibernate: select ... from threat_actors <span class="hljs-built_in">limit</span> ? offset ? -- ✅ ONLY ONE QUERY
</code></pre>
<hr />
<h2 id="heading-4-conclusion"><strong>4. Conclusion</strong></h2>
<p>By combining the <strong>Specification Pattern</strong> with <strong>Slice Pagination</strong>, we achieved:</p>
<ol>
<li><p><strong>Cleaner Code:</strong> Zero boilerplate for dynamic filters.</p>
</li>
<li><p><strong>Better Performance:</strong> 50% fewer queries for infinite scroll views.</p>
</li>
</ol>
<p>Check out the full implementation in the <a target="_blank" href="https://github.com/prasadgaikwad/spring-data-jpa-specification">repository</a>!</p>
<h3 id="heading-references"><strong>References</strong></h3>
<ul>
<li><p><a target="_blank" href="https://github.com/prasadgaikwad/spring-data-jpa-specification">https://github.com/prasadgaikwad/spring-data-jpa-specification</a></p>
</li>
<li><p><a target="_blank" href="https://gist.github.com/josergdev/06c82891a719eca4834410339885ad23">https://gist.github.com/josergdev/06c82891a719eca4834410339885ad23</a></p>
</li>
<li><p><a target="_blank" href="https://docs.spring.io/spring-data/jpa/reference/jpa/specifications.html">Spring Data JPA Specifications</a></p>
</li>
<li><p><a target="_blank" href="https://vladmihalcea.com/spring-data-jpa-specification/">Vlad Mihalcea: The best way to use the Spring Data JPA Specification</a></p>
</li>
</ul>
]]></content:encoded></item><item><title><![CDATA[Getting Started with LangChain4j: Building Your First AI-Powered Java Application]]></title><description><![CDATA[In this blog post, we'll walk through creating your first LangChain4j application using Spring Boot. We'll build a simple interactive command-line application that demonstrates the basic setup and usage of LangChain4j in a Java environment.
What is L...]]></description><link>https://blog.prasadgaikwad.dev/getting-started-with-langchain4j-building-your-first-ai-powered-java-application</link><guid isPermaLink="true">https://blog.prasadgaikwad.dev/getting-started-with-langchain4j-building-your-first-ai-powered-java-application</guid><category><![CDATA[langchain4j]]></category><category><![CDATA[Java]]></category><category><![CDATA[Springboot]]></category><category><![CDATA[AI]]></category><dc:creator><![CDATA[Prasad Gaikwad]]></dc:creator><pubDate>Tue, 04 Nov 2025 04:14:03 GMT</pubDate><content:encoded><![CDATA[<p>In this blog post, we'll walk through creating your first LangChain4j application using Spring Boot. We'll build a simple interactive command-line application that demonstrates the basic setup and usage of LangChain4j in a Java environment.</p>
<h2 id="heading-what-is-langchain4j"><strong>What is LangChain4j?</strong></h2>
<p>LangChain4j is a powerful Java framework designed to simplify the development of applications powered by Large Language Models (LLMs). It provides a comprehensive set of tools and abstractions that make it easier to build sophisticated AI-powered applications.</p>
<h2 id="heading-project-setup"><strong>Project Setup</strong></h2>
<h3 id="heading-prerequisites"><strong>Prerequisites</strong></h3>
<ul>
<li><p>Java 17 or higher</p>
</li>
<li><p>Maven</p>
</li>
<li><p>Your favorite IDE (IntelliJ IDEA, Eclipse, or VS Code)</p>
</li>
<li><p>An API key from your chosen LLM provider (e.g., OpenAI)</p>
</li>
</ul>
<h3 id="heading-step-1-create-a-spring-boot-project"><strong>Step 1: Create a Spring Boot Project</strong></h3>
<p>Start by creating a new Spring Boot project using Spring Initializr or your IDE. We'll need the following dependencies:</p>
<ul>
<li><p>Spring Boot Starter</p>
</li>
<li><p>LangChain4j BOM (Bill of Materials)</p>
</li>
</ul>
<p>Here's our <code>pom.xml</code> configuration:</p>
<pre><code class="lang-xml"><span class="hljs-comment">&lt;!-- Parent Spring Boot --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">parent</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter-parent<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>3.5.7<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">parent</span>&gt;</span>

<span class="hljs-comment">&lt;!-- LangChain4j BOM for version management --&gt;</span>
<span class="hljs-tag">&lt;<span class="hljs-name">dependencyManagement</span>&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>dev.langchain4j<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>langchain4j-bom<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">version</span>&gt;</span>1.8.0<span class="hljs-tag">&lt;/<span class="hljs-name">version</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">type</span>&gt;</span>pom<span class="hljs-tag">&lt;/<span class="hljs-name">type</span>&gt;</span>
            <span class="hljs-tag">&lt;<span class="hljs-name">scope</span>&gt;</span>import<span class="hljs-tag">&lt;/<span class="hljs-name">scope</span>&gt;</span>
        <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencyManagement</span>&gt;</span>

<span class="hljs-tag">&lt;<span class="hljs-name">dependencies</span>&gt;</span>
    <span class="hljs-comment">&lt;!-- Spring Boot Starter --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>org.springframework.boot<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>spring-boot-starter<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>

    <span class="hljs-comment">&lt;!-- LangChain4j OpenAI Integration --&gt;</span>
    <span class="hljs-tag">&lt;<span class="hljs-name">dependency</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">groupId</span>&gt;</span>dev.langchain4j<span class="hljs-tag">&lt;/<span class="hljs-name">groupId</span>&gt;</span>
        <span class="hljs-tag">&lt;<span class="hljs-name">artifactId</span>&gt;</span>langchain4j-open-ai<span class="hljs-tag">&lt;/<span class="hljs-name">artifactId</span>&gt;</span>
    <span class="hljs-tag">&lt;/<span class="hljs-name">dependency</span>&gt;</span>
<span class="hljs-tag">&lt;/<span class="hljs-name">dependencies</span>&gt;</span>
</code></pre>
<h3 id="heading-step-2-configuration"><strong>Step 2: Configuration</strong></h3>
<p>Create or update your <code>.env</code> file: (make sure to add this .env file to your .gitignore to keep your API key secure)</p>
<pre><code class="lang-plaintext"># OpenAI API Configuration
OPENAI_API_KEY=your-api-key-here
</code></pre>
<h3 id="heading-step-3-creating-the-application"><strong>Step 3: Creating the Application</strong></h3>
<p>We'll create a simple command-line application that:</p>
<ol>
<li><p>Asks for user's question</p>
</li>
<li><p>Answers concisely using the OpenAI GPT-4o-mini model</p>
</li>
<li><p>Continues interaction until they type 'quit'</p>
</li>
</ol>
<p>The implementation uses Spring's CommandLineRunner for the interactive loop.</p>
<h2 id="heading-understanding-the-code"><strong>Understanding the Code</strong></h2>
<p>Let's break down the key components:</p>
<ol>
<li><strong>The Main Application Class</strong></li>
</ol>
<pre><code class="lang-java">
<span class="hljs-meta">@SpringBootApplication</span>
<span class="hljs-keyword">public</span> <span class="hljs-class"><span class="hljs-keyword">class</span> <span class="hljs-title">LangChain4jDemoApplication</span> <span class="hljs-keyword">implements</span> <span class="hljs-title">CommandLineRunner</span> </span>{

    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">static</span> <span class="hljs-keyword">void</span> <span class="hljs-title">main</span><span class="hljs-params">(String[] args)</span> </span>{
        SpringApplication.run(LangChain4jDemoApplication.class, args);
    }

    /**
     * A simple command-line application that interacts with the user,
     * takes a question as input, and provides a concise answer using
     * the OpenAI GPT-<span class="hljs-number">4</span>o-mini model.
     */
    <span class="hljs-meta">@Override</span>
    <span class="hljs-function"><span class="hljs-keyword">public</span> <span class="hljs-keyword">void</span> <span class="hljs-title">run</span><span class="hljs-params">(String... args)</span> </span>{
        ChatModel model = OpenAiChatModel.builder()
                .apiKey(System.getenv(<span class="hljs-string">"OPENAI_API_KEY"</span>))
                .modelName(<span class="hljs-string">"gpt-4o-mini"</span>)
                .build();

        <span class="hljs-keyword">try</span> (Scanner scanner = <span class="hljs-keyword">new</span> Scanner(System.in)) {
            <span class="hljs-keyword">while</span> (<span class="hljs-keyword">true</span>) {
                System.out.print(<span class="hljs-string">"Please enter your question (type 'quit' to exit): "</span>);
                String question = scanner.nextLine();

                <span class="hljs-keyword">if</span> (<span class="hljs-string">"quit"</span>.equalsIgnoreCase(question)) {
                    System.out.println(<span class="hljs-string">"Goodbye!"</span>);
                    <span class="hljs-keyword">break</span>;
                }

                String response = model.chat(<span class="hljs-string">"You are an helpful assistant. "</span> +
                        <span class="hljs-string">"Answer this question in very concise way, only in 2 sentences maximum. Question: "</span> + question);
                System.out.println(<span class="hljs-string">"Answer: "</span> + response);
                System.out.println(); <span class="hljs-comment">// Add a blank line for better readability</span>
            }
        }
    }
}
</code></pre>
<h2 id="heading-running-the-application"><strong>Running the Application</strong></h2>
<p>To run the application:</p>
<ol>
<li><p>Ensure you have set your API key in <code>.env</code> file</p>
</li>
<li><p>Run the following command:</p>
<pre><code class="lang-plaintext"> ./mvnw spring-boot:run
</code></pre>
</li>
</ol>
<h2 id="heading-next-steps"><strong>Next Steps</strong></h2>
<p>This basic setup provides a foundation for exploring more advanced LangChain4j features:</p>
<ol>
<li><p><strong>Adding LLM Integration</strong></p>
<ul>
<li><p>Implement chat completions</p>
</li>
<li><p>Add streaming responses</p>
</li>
<li><p>Experiment with different models</p>
</li>
</ul>
</li>
<li><p><strong>Implementing Memory</strong></p>
<ul>
<li><p>Add conversation history</p>
</li>
<li><p>Implement different memory types</p>
</li>
</ul>
</li>
<li><p><strong>Creating Chains</strong></p>
<ul>
<li><p>Build processing pipelines</p>
</li>
<li><p>Add prompt templates</p>
</li>
</ul>
</li>
</ol>
<h2 id="heading-resources"><strong>Resources</strong></h2>
<p>For more information and advanced features, check out:</p>
<ul>
<li><p><a target="_blank" href="https://docs.langchain4j.dev/">Official LangChain4j Documentation</a></p>
</li>
<li><p><a target="_blank" href="https://github.com/langchain4j/langchain4j-examples">GitHub Examples Repository</a></p>
</li>
</ul>
<h2 id="heading-conclusion"><strong>Conclusion</strong></h2>
<p>This simple example demonstrates how easy it is to get started with LangChain4j. The framework's integration with Spring Boot makes it particularly attractive for Java developers looking to build AI-powered applications.</p>
<p>Stay tuned for more blog posts where we'll explore advanced features like:</p>
<ul>
<li><p>Working with different LLM providers</p>
</li>
<li><p>Implementing RAG (Retrieval Augmented Generation)</p>
</li>
<li><p>Building custom agents and tools</p>
</li>
<li><p>Creating sophisticated conversation chains</p>
</li>
</ul>
<p>Remember to check out our <a target="_blank" href="https://github.com/prasadgaikwad/langchain4j-demo">GitHub repository</a> for the complete source code and future updates!</p>
]]></content:encoded></item><item><title><![CDATA[How I created my blog in 10 minutes!]]></title><description><![CDATA[Note: The steps mentioned here are specifically for Google DNS, a .dev domain and Hashnode.

So I wanted to create my blog and online profile for quite some time but was not sure about following:

How to start the blog?
How to register a domain name ...]]></description><link>https://blog.prasadgaikwad.dev/how-i-created-my-blog-in-10-minutes</link><guid isPermaLink="true">https://blog.prasadgaikwad.dev/how-i-created-my-blog-in-10-minutes</guid><category><![CDATA[Developer Blogging]]></category><category><![CDATA[Programming Blogs]]></category><category><![CDATA[Blogging]]></category><category><![CDATA[blog]]></category><category><![CDATA[Hashnode]]></category><dc:creator><![CDATA[Prasad Gaikwad]]></dc:creator><pubDate>Fri, 01 Jan 2021 16:18:34 GMT</pubDate><content:encoded><![CDATA[<blockquote>
<p>Note: The steps mentioned here are specifically for Google DNS, a .dev domain and Hashnode.</p>
</blockquote>
<p>So I wanted to create my blog and online profile for quite some time but was not sure about following:</p>
<ol>
<li>How to start the blog?</li>
<li>How to register a domain name and setup?</li>
<li>Should I use any blogging platform or build my own blog?</li>
<li>Which blogging platform to use?</li>
</ol>
<p>And after researching for a while, I decided to create my blog today to check this item off my list on very first day of the year :)</p>
<p>Here is a short tutorial on how to create a blog, setup your own domain name and use the domain name to redirect to your blog, all about in 10 minutes. (off course it took some time for me to research on the options for blogging platforms, domain name service providers etc, but actual process of blog setup took about 10 minutes!)</p>
<h1 id="my-choices">My Choices</h1>
<ul>
<li>I chose <a target="_blank" href="https://domains.google.com/">Google Domains</a> as my domain name service (DNS) provider to avoid getting too much into the weeds for searching a DNS provider. During my initial research, I found it has features which I required to get started quickly. </li>
<li>I picked <a target="_blank" href="https://hashnode.com/">Hashnode</a> as my blogging platform since I found that it provides a lot of useful features in addition to the ease of creating and maintaining a blog.</li>
</ul>
<h1 id="prerequisites">Prerequisites</h1>
<ol>
<li>You need a google/gmail account to buy domain name from google.</li>
<li>Create an account with Hashnode to get you started (you don't need steps for this, believe me ;)) </li>
</ol>
<h1 id="steps">Steps</h1>
<ol>
<li>Search for your required domain name at <a target="_blank" href="https://domains.google.com/">Google Domains</a>, add it to the cart and proceed.
You should see something like following on next screen:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609529870646/WLq97Uwyg.png" alt="image.png" /></li>
<li>Provide required contact information on checkout screen. 
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609530136994/ZtlCq1VK2.png" alt="image.png" /></li>
<li>Provide payment information and checkout. That's it! You own the domain name now! You may have to verify your email address for the domain purchase.</li>
<li>On your Hashnode blog dashboard page, add your domain name (in my case I used a subdomain blog.prasadgaikwad.dev) under DOMAIN tab and click update. You will see next steps on the same page as shown below:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609530572227/rxmEuzi2WJ.png" alt="image.png" /></li>
<li>Go back to your Google Domains dashboard and select the newly created domain name to go into its settings.</li>
<li>Go to DNS section and scroll to the "Custom resource records" section. Add CNAME record as shown below:
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609530956828/y2Idz3sBS.png" alt="image.png" />
(Note that I am using a subdomain "blog" since Google Domains does not support CNAME record for root domain. You can create any subdomain)</li>
<li>Wait for few minutes and go to your subdomain url, you should see your Hashnode blog!
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609531345453/e9u7ckSJo.png" alt="image.png" /></li>
<li>Wait for it...you may also want to redirect your root domain (in my case  <a target="_blank" href="https://prasadgaikwad.dev">prasadgaikwad.dev</a>  and  <a target="_blank" href="https://www.prasadgaikwad.dev">www.prasadgaikwad.dev</a>), then go the Website section of your Google Domains page and add Forward domain details. (In my case I forwarded my root domain to my blog subdomain for now!)
<img src="https://cdn.hashnode.com/res/hashnode/image/upload/v1609531593479/FKspWiQib.png" alt="image.png" /></li>
<li>You may have to hard refresh (command + r) browser page with your domain url, to delete any cached pages or errors.</li>
<li>And that's all you need to get your own developer blog started on your custom domain.</li>
</ol>
<h1 id="references">References:</h1>
<ol>
<li><a target="_blank" href="https://hashnode.com/post/how-to-set-up-a-custom-domain-on-devblog-cjvoymax9001u8xs1i9f3077e">How to Set Up a Custom Domain on Devblog</a> </li>
<li><a target="_blank" href="https://www.freecodecamp.org/news/devblog-launch-your-developer-blog-own-domain/">Hashnode: How to Launch Your Own Developer Blog on Your Own Domain in Minutes</a> </li>
</ol>
<p>(I created this blog post to document steps which I could not find in reference blogs, so that it might be useful if someone decides to use these platforms like me) </p>
]]></content:encoded></item></channel></rss>