<?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: Shubham Bhilare</title>
    <description>The latest articles on DEV Community by Shubham Bhilare (@shubham_bhilare_3611).</description>
    <link>https://dev.to/shubham_bhilare_3611</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%2F3162369%2F0efb9717-daa8-42e7-a245-65cb4b397250.png</url>
      <title>DEV Community: Shubham Bhilare</title>
      <link>https://dev.to/shubham_bhilare_3611</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/shubham_bhilare_3611"/>
    <language>en</language>
    <item>
      <title>Build Portfolio Website in Seconds</title>
      <dc:creator>Shubham Bhilare</dc:creator>
      <pubDate>Mon, 29 Sep 2025 09:07:59 +0000</pubDate>
      <link>https://dev.to/shubham_bhilare_3611/build-portfolio-website-in-seconds-4agg</link>
      <guid>https://dev.to/shubham_bhilare_3611/build-portfolio-website-in-seconds-4agg</guid>
      <description>&lt;p&gt;⚡ Big news!&lt;br&gt;
 GitFolio  is FREE to try with ALL templates unlocked – build your dev portfolio and launch it instantly 🌎✨&lt;br&gt;
🚀 Get started 👉 &lt;a href="https://gitfolio.in" rel="noopener noreferrer"&gt;GitFolio&lt;/a&gt;Explore All Templates for Free&lt;/p&gt;

&lt;p&gt;No Coding , No Debugging 🫣 &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%2F8o69gnwz4dmowppbdsok.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%2F8o69gnwz4dmowppbdsok.png" alt="Pricing" width="800" height="453"&gt;&lt;/a&gt;&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%2F4qo5vi96lqs921wkkzhh.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%2F4qo5vi96lqs921wkkzhh.png" alt="Template" width="800" height="450"&gt;&lt;/a&gt;&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%2Fhr2m1hxbpwykhnitwv0p.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%2Fhr2m1hxbpwykhnitwv0p.png" alt="Template" width="800" height="455"&gt;&lt;/a&gt;&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%2F0izja6qis7vj2ynz0rab.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%2F0izja6qis7vj2ynz0rab.png" alt="Template" width="800" height="454"&gt;&lt;/a&gt;&lt;/p&gt;

</description>
      <category>portfolio</category>
      <category>webdev</category>
      <category>productivity</category>
      <category>opensource</category>
    </item>
    <item>
      <title>New Portfolio Template</title>
      <dc:creator>Shubham Bhilare</dc:creator>
      <pubDate>Fri, 12 Sep 2025 21:47:45 +0000</pubDate>
      <link>https://dev.to/shubham_bhilare_3611/added-new-template-4eln</link>
      <guid>https://dev.to/shubham_bhilare_3611/added-new-template-4eln</guid>
      <description>&lt;p&gt;Added a New template to &lt;a href="//www.gitfolio.in"&gt;GitFolio&lt;/a&gt;&lt;br&gt;
Built for developers who'd rather code than design — we make your GitHub shine so you can focus on building.&lt;/p&gt;

&lt;p&gt;Template named Clean Slate&lt;br&gt;
A minimal light/dark mode portfolio site that focuses on projects.&lt;/p&gt;

&lt;p&gt;Here's the official tweet&lt;br&gt;&lt;br&gt;
&lt;iframe class="tweet-embed" id="tweet-1966614271716192770-922" src="https://platform.twitter.com/embed/Tweet.html?id=1966614271716192770"&gt;
&lt;/iframe&gt;

  // Detect dark theme
  var iframe = document.getElementById('tweet-1966614271716192770-922');
  if (document.body.className.includes('dark-theme')) {
    iframe.src = "https://platform.twitter.com/embed/Tweet.html?id=1966614271716192770&amp;amp;theme=dark"
  }



&lt;/p&gt;

&lt;p&gt;You can see a demo portfolio  &lt;a href="https://portfolio.gitfolio.in/Clean%20Slate" rel="noopener noreferrer"&gt;here&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you like Do visit &lt;a href="//www.gitfolio.in"&gt;GitFolio&lt;/a&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>saas</category>
      <category>portfolio</category>
      <category>startup</category>
    </item>
    <item>
      <title>Render.com Latency Fix</title>
      <dc:creator>Shubham Bhilare</dc:creator>
      <pubDate>Thu, 14 Aug 2025 09:10:05 +0000</pubDate>
      <link>https://dev.to/shubham_bhilare_3611/rendercom-latency-fix-ipd</link>
      <guid>https://dev.to/shubham_bhilare_3611/rendercom-latency-fix-ipd</guid>
      <description>&lt;p&gt;&lt;a href="//render.com"&gt;Render&lt;/a&gt; free tier (Hobby Projects) is good for development but when it comes to prod it sucks.&lt;br&gt;
It clearly states that&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Your free instance will spin down with inactivity, which can delay requests by 50 seconds or more.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;and 50 secs is a terrible amount of latency 😥&lt;/p&gt;

&lt;p&gt;So to tackle this on free tier i have setup a uptime service using &lt;a href="//uptimerobot.com"&gt;Uptime Robot&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This platform pings your service every 5 mins (free tier) and if you want to cut this time further then you can upgrade your account&lt;/p&gt;

&lt;p&gt;Simply create a monitor and enter your "/" or "/health" endpoint and your instance will get a req every 5 min&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Problem Solved ✅&lt;/strong&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>programming</category>
      <category>backend</category>
      <category>uptime</category>
    </item>
    <item>
      <title>GitFolio - Dev Portfolio in Seconds</title>
      <dc:creator>Shubham Bhilare</dc:creator>
      <pubDate>Sun, 03 Aug 2025 12:22:41 +0000</pubDate>
      <link>https://dev.to/shubham_bhilare_3611/gitfolio-dev-portfolio-in-seconds-5djg</link>
      <guid>https://dev.to/shubham_bhilare_3611/gitfolio-dev-portfolio-in-seconds-5djg</guid>
      <description>&lt;h2&gt;
  
  
  👋Introduction
&lt;/h2&gt;

&lt;p&gt;As a developer all we have is our &lt;em&gt;&lt;strong&gt;Github&lt;/strong&gt;&lt;/em&gt; porfile! We spend hours building our products, do &lt;em&gt;open-source&lt;/em&gt; and pushing to prod... but when its time to show our work, all we have is the same &lt;em&gt;&lt;strong&gt;github profile&lt;/strong&gt;&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;So to solve this problem, I'll like to introduce you to &lt;a href="https://gitfolio-dev.vercel.app" rel="noopener noreferrer"&gt;&lt;strong&gt;&lt;em&gt;GitFolio&lt;/em&gt;&lt;/strong&gt;&lt;/a&gt; with the vision of   &lt;strong&gt;&lt;em&gt;"Turning Your Github Profile into Portfolio Sites in Seconds."&lt;/em&gt; &lt;br&gt;
*&lt;em&gt;No coding, No Markdown. Just Connect your *&lt;/em&gt;&lt;em&gt;Github&lt;/em&gt;&lt;/strong&gt;,select a &lt;strong&gt;&lt;em&gt;template&lt;/em&gt;&lt;/strong&gt;, and &lt;em&gt;&lt;strong&gt;boom 💥&lt;/strong&gt;&lt;/em&gt; your site is &lt;strong&gt;&lt;em&gt;live✅&lt;/em&gt;&lt;/strong&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  🚀 What is GitFolio?
&lt;/h3&gt;

&lt;p&gt;GitFolio is a free to use platform that helps you showcase your &lt;strong&gt;&lt;em&gt;Github&lt;/em&gt;&lt;/strong&gt; profile in an amazing way !&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;Because &lt;em&gt;Your GitHub already tells your story — now turnit into a personal site that speaks for itself&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Why I Built GitFolio ?
&lt;/h3&gt;

&lt;p&gt;I've seen many developers, including myself ignoring making personal portfolio sites. Rather than that they focus on building new projects/products. &lt;br&gt;
They do not want to invest time in making portfolio websites and maintaining it.&lt;br&gt;
Meanwhile, &lt;em&gt;Github&lt;/em&gt; already contains 90% of your data, projects, skills, contributions and many more...&lt;br&gt;
So why not use it ?&lt;/p&gt;

&lt;p&gt;So I thought of making a platform that'll help developers including myself , in creating and maintaining of the &lt;em&gt;personal portfolio _site with a &lt;strong&gt;live hosted URl&lt;/strong&gt; just by connecting &lt;strong&gt;Github!&lt;/strong&gt;&lt;/em&gt; .&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;a href="https://gitfolio-template.vercel.app/Black%20&amp;amp;%20White/Skb3611" rel="noopener noreferrer"&gt;Sample Portfolio&lt;/a&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  How it Works ⚙️
&lt;/h3&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;Connect your &lt;em&gt;&lt;strong&gt;Github&lt;/strong&gt;&lt;/em&gt; account.&lt;br&gt;
&lt;em&gt;(read-only-access ||no scary permissions and private repos initially)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Pick a Template&lt;br&gt;
&lt;em&gt;(Clean modern responsive templates available - currently launching with 1 template)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Done ✅ - &lt;em&gt;You're Live&lt;/em&gt; &lt;br&gt;
&lt;em&gt;(Copy your public access link or just visit your portfolio.)&lt;/em&gt;&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;
&lt;h3&gt;
  
  
  Features
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;GitHub-powered Data&lt;/li&gt;
&lt;li&gt;Personal Dashboard for necessary changes.&lt;/li&gt;
&lt;li&gt;Clean , mobile-responsive templates. (Currently only 1 available)&lt;/li&gt;
&lt;li&gt;Instant deploy (no build process, ready within seconds !)&lt;/li&gt;
&lt;li&gt;Shareable public links&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Who It's For?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;All Developer Community&lt;/li&gt;
&lt;li&gt;Students applying for internships&lt;/li&gt;
&lt;li&gt;Anyone who has got less time and need a portfolio on urgent basis&lt;/li&gt;
&lt;li&gt;Every developer who wants their online presence&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;
  
  
  Whats Upcoming?
&lt;/h3&gt;

&lt;ul&gt;
&lt;li&gt;Multiple templates&lt;/li&gt;
&lt;li&gt;Real time data - sync from &lt;em&gt;&lt;strong&gt;Github&lt;/strong&gt;&lt;/em&gt;
&lt;/li&gt;
&lt;li&gt;Auto Generated SEO support
and many more ...&lt;/li&gt;
&lt;/ul&gt;

&lt;blockquote&gt;
&lt;p&gt;If you’ve got a GitHub, you’ve already got a portfolio — GitFolio just brings it to life.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h3&gt;
  
  
  Help Me Improve It 📢
&lt;/h3&gt;

&lt;p&gt;GitFolio is still in its early MVP phase.&lt;br&gt;
I’d love feedback, suggestions, and early users!&lt;br&gt;
&lt;a href="https://www.linkedin.com/in/shubham-bhilare-0a694a309/" rel="noopener noreferrer"&gt;Connect on Linkedin&lt;/a&gt;&lt;br&gt;
&lt;a href="https://x.com/SKB3611" rel="noopener noreferrer"&gt;Connect on Twitter&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Final Thoughts 💬
&lt;/h3&gt;

&lt;p&gt;In a world where “you are what you ship,” your portfolio matters.&lt;/p&gt;

&lt;p&gt;GitFolio helps you show what you’ve built — without building the portfolio itself.&lt;/p&gt;

&lt;p&gt;If you try it, tweet me or tag me with your portfolio — I’d love to share it.&lt;br&gt;
Let’s help more devs put themselves out there. 🚀&lt;br&gt;
&lt;/p&gt;
&lt;div class="crayons-card c-embed text-styles text-styles--secondary"&gt;
    &lt;div class="c-embed__content"&gt;
        &lt;div class="c-embed__cover"&gt;
          &lt;a href="https://www.gitfolio.in/" class="c-link align-middle" rel="noopener noreferrer"&gt;
            &lt;img alt="" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fgitfolio.in%2Fassets%2Fog.png" height="auto" class="m-0"&gt;
          &lt;/a&gt;
        &lt;/div&gt;
      &lt;div class="c-embed__body"&gt;
        &lt;h2 class="fs-xl lh-tight"&gt;
          &lt;a href="https://www.gitfolio.in/" rel="noopener noreferrer" class="c-link"&gt;
            Gitfolio - From GitHub to Portfolio.
          &lt;/a&gt;
        &lt;/h2&gt;
          &lt;p class="truncate-at-3"&gt;
            Turn Your GitHub Into a Personal Portfolio in Seconds. Built for developers who'd rather code than design — we make your GitHub shine so you can focus on building.
          &lt;/p&gt;
        &lt;div class="color-secondary fs-s flex items-center"&gt;
            &lt;img alt="favicon" class="c-embed__favicon m-0 mr-2 radius-0" src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fwww.gitfolio.in%2Ffavicon.ico%3Ffavicon.9551a794.ico"&gt;
          gitfolio.in
        &lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
&lt;/div&gt;


</description>
      <category>saas</category>
      <category>productivity</category>
      <category>portfolio</category>
      <category>github</category>
    </item>
    <item>
      <title>Mastering AWS S3 with JavaScript: S3Client Config &amp; Most Useful Commands 🚀</title>
      <dc:creator>Shubham Bhilare</dc:creator>
      <pubDate>Thu, 05 Jun 2025 07:43:20 +0000</pubDate>
      <link>https://dev.to/shubham_bhilare_3611/mastering-aws-s3-with-javascript-s3client-config-most-useful-commands-2d60</link>
      <guid>https://dev.to/shubham_bhilare_3611/mastering-aws-s3-with-javascript-s3client-config-most-useful-commands-2d60</guid>
      <description>&lt;p&gt;Whether you're building a full-stack app or managing static assets, &lt;strong&gt;Amazon S3&lt;/strong&gt; is a go-to service for scalable storage. In this post, we’ll break down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;📦 S3Client setup (with &lt;code&gt;@aws-sdk/client-s3&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;⚙️ Most useful operations: creating/deleting buckets, uploading/downloading files&lt;/li&gt;
&lt;li&gt;🔁 A simple workflow you can apply to your own app&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔧 Setting Up the AWS S3 Client
&lt;/h2&gt;

&lt;p&gt;First, install the SDK:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;npm &lt;span class="nb"&gt;install&lt;/span&gt; @aws-sdk/client-s3
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Then configure your client:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// config/s3Client.js&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;S3Client&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;S3Client&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;region&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;your-region&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="c1"&gt;// e.g., 'us-east-1'&lt;/span&gt;
  &lt;span class="na"&gt;credentials&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;accessKeyId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_ACCESS_KEY_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;secretAccessKey&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;AWS_SECRET_ACCESS_KEY&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;});&lt;/span&gt;

&lt;span class="k"&gt;export&lt;/span&gt; &lt;span class="k"&gt;default&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;💡 Best Practice: Store your credentials securely using environment variables or IAM roles (if you're using Lambda/EC2).&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  📚 Most Useful S3 Commands
&lt;/h2&gt;

&lt;h3&gt;
  
  
  ✅ 1. Create a Bucket
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;CreateBucketCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;CreateBucketCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-awesome-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  🗑️ 2. Delete a Bucket
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DeleteBucketCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DeleteBucketCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-awesome-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📤 3. Upload an Object
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;PutObjectCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;fileStream&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createReadStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./example.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PutObjectCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-awesome-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;fileStream&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📥 4. Download an Object
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;GetObjectCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;fs&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;fs&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;GetObjectCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-awesome-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;pipe&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;fs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;createWriteStream&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;./downloaded.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  ❌ 5. Delete an Object
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;DeleteObjectCommand&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;DeleteObjectCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-awesome-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;example.txt&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  📃 6. List Objects in a Bucket
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;ListObjectsV2Command&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;@aws-sdk/client-s3&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;ListObjectsV2Command&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-awesome-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}));&lt;/span&gt;

&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Contents&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧠 Workflow Example: Image Upload API
&lt;/h2&gt;

&lt;p&gt;Here’s a simple idea of how your workflow could look in a backend:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;User uploads an image&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Frontend sends file to backend&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Backend uploads file to S3&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;S3 returns URL&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;URL saved in DB&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;URL sent back to frontend&lt;/strong&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight jsx"&gt;&lt;code&gt;&lt;span class="c1"&gt;// Upload and return URL&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;uploadToS3&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;async &lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;s3Client&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;send&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nc"&gt;PutObjectCommand&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;Bucket&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;my-awesome-bucket&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Key&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;Body&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;ContentType&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;file&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;mimetype&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;}));&lt;/span&gt;

  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s2"&gt;`https://&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;yourBucket&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.s3.&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;yourRegion&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;.amazonaws.com/&lt;/span&gt;&lt;span class="p"&gt;${&lt;/span&gt;&lt;span class="nx"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;`&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;






&lt;h2&gt;
  
  
  🧪 Extra Commands to Explore
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;CopyObjectCommand&lt;/code&gt; – Duplicate files&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;HeadObjectCommand&lt;/code&gt; – Check if file exists&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;PutObjectAclCommand&lt;/code&gt; – Make file public&lt;/li&gt;
&lt;li&gt;Multipart Upload – For large files (&amp;gt;5MB)&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  ✅ Final Thoughts
&lt;/h2&gt;

&lt;p&gt;The AWS SDK v3 makes working with S3 modular and easy. With the right config and a clean workflow, integrating S3 into your app is seamless. If you’re building a file uploader, static hosting solution, or media management API—this toolkit is all you need to start strong.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;💬 Have questions or want to see this workflow in Express, Next.js, or NestJS? Drop a comment!&lt;/p&gt;
&lt;/blockquote&gt;

</description>
      <category>cloud</category>
      <category>cloudstorage</category>
      <category>aws</category>
      <category>webdev</category>
    </item>
    <item>
      <title>How to Fix LinkedIn Authentication in NextAuth.js: A Custom Provider Setup Guide</title>
      <dc:creator>Shubham Bhilare</dc:creator>
      <pubDate>Sat, 17 May 2025 21:45:47 +0000</pubDate>
      <link>https://dev.to/shubham_bhilare_3611/how-to-fix-linkedin-authentication-in-nextauthjs-a-custom-provider-setup-guide-5g8f</link>
      <guid>https://dev.to/shubham_bhilare_3611/how-to-fix-linkedin-authentication-in-nextauthjs-a-custom-provider-setup-guide-5g8f</guid>
      <description>&lt;h2&gt;
  
  
  A Quick Guide to Getting LinkedIn OAuth Working Correctly
&lt;/h2&gt;




&lt;p&gt;LinkedIn authentication is a powerful feature to add to your Next.js application using &lt;strong&gt;NextAuth.js&lt;/strong&gt;, but the default configuration can often lead to issues — especially when trying to fetch user details like email, name, and profile picture.&lt;/p&gt;

&lt;p&gt;In this article, I’ll walk you through how I solved this issue by customizing the LinkedIn provider configuration in NextAuth.js.&lt;/p&gt;




&lt;h2&gt;
  
  
  🧪 The Problem
&lt;/h2&gt;

&lt;p&gt;Using the default &lt;code&gt;LinkedInProvider&lt;/code&gt; setup from &lt;code&gt;next-auth/providers/linkedin&lt;/code&gt; may not always return complete user information such as email or profile picture.&lt;/p&gt;

&lt;h3&gt;
  
  
  🔧 Default Implementation
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="k"&gt;import&lt;/span&gt; &lt;span class="nx"&gt;LinkedInProvider&lt;/span&gt; &lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;next-auth/providers/linkedin&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

&lt;span class="nl"&gt;providers&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
  &lt;span class="nc"&gt;LinkedInProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LINKEDIN_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LINKEDIN_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This basic setup often results in incomplete data being returned from LinkedIn.&lt;/p&gt;




&lt;h2&gt;
  
  
  ✅ The Fix
&lt;/h2&gt;

&lt;p&gt;To overcome this, I had to dig into LinkedIn’s OAuth docs and customize the &lt;code&gt;LinkedInProvider&lt;/code&gt; to manually specify scopes, endpoints, and userinfo configurations.&lt;/p&gt;

&lt;h3&gt;
  
  
  💡 Working LinkedInProvider Configuration
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;LinkedInProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LINKEDIN_CLIENT_ID&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;LINKEDIN_CLIENT_SECRET&lt;/span&gt; &lt;span class="o"&gt;??&lt;/span&gt; &lt;span class="dl"&gt;""&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;client&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="na"&gt;token_endpoint_auth_method&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;client_secret_post&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;r_liteprofile r_emailaddress&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;issuer&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.linkedin.com&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;userinfo&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://api.linkedin.com/v2/userinfo&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;token&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.linkedin.com/oauth/v2/accessToken&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;wellKnown&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.linkedin.com/oauth/.well-known/openid-configuration&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;authorization&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="na"&gt;url&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.linkedin.com/oauth/v2/authorization&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="na"&gt;params&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;scope&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;profile email openid&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;prompt&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;consent&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;access_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;offline&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;response_type&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;code&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
  &lt;span class="na"&gt;jwks_endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;https://www.linkedin.com/oauth/openid/jwks&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;async&lt;/span&gt; &lt;span class="nf"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="na"&gt;id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;firstname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;given_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;lastname&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;family_name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;email&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;email&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="na"&gt;image&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;profile&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;picture&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="p"&gt;};&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt;
&lt;span class="p"&gt;}),&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This configuration ensures you:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Request proper scopes like &lt;code&gt;r_emailaddress&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;Use the correct LinkedIn OAuth endpoints&lt;/li&gt;
&lt;li&gt;Get a complete &lt;code&gt;profile&lt;/code&gt; object including email and picture&lt;/li&gt;
&lt;/ul&gt;




&lt;h2&gt;
  
  
  🔐 Bonus Tip: Twitter Provider Email Issue
&lt;/h2&gt;

&lt;p&gt;If you're using &lt;strong&gt;Twitter authentication&lt;/strong&gt; as well, make sure you &lt;strong&gt;enable email access&lt;/strong&gt; in your Twitter app settings. Without this, you won’t get the user’s email address.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nc"&gt;TwitterProvider&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
  &lt;span class="na"&gt;clientId&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TWITTER_CLIENT_ID&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="na"&gt;clientSecret&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nx"&gt;process&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;TWITTER_CLIENT_SECRET&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;✅ &lt;strong&gt;Tip:&lt;/strong&gt; Enable "Request email address from users" in Twitter Developer Portal.&lt;/p&gt;
&lt;/blockquote&gt;




&lt;h2&gt;
  
  
  🧵 TL;DR
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Default &lt;code&gt;LinkedInProvider&lt;/code&gt; doesn’t return complete user info.&lt;/li&gt;
&lt;li&gt;Customize it with the right OAuth config to fix it.&lt;/li&gt;
&lt;li&gt;Twitter requires email permission to return user emails.&lt;/li&gt;
&lt;/ul&gt;




&lt;p&gt;Thanks for reading! 🚀&lt;/p&gt;

&lt;p&gt;If you found this helpful, consider following me on &lt;a href="https://x.com/SKB3611" rel="noopener noreferrer"&gt;Twitter&lt;/a&gt; and checking out my other projects like &lt;a href="https://resume-org.vercel.app/" rel="noopener noreferrer"&gt;Resume Builder&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let me know if you’ve faced similar issues or need help with OAuth in your apps! 💬&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>nextauth</category>
      <category>nextjs</category>
      <category>authjs</category>
    </item>
    <item>
      <title>How I Created a Full-Stack Resume Builder Using Next.js and Prisma</title>
      <dc:creator>Shubham Bhilare</dc:creator>
      <pubDate>Sat, 17 May 2025 07:51:06 +0000</pubDate>
      <link>https://dev.to/shubham_bhilare_3611/how-i-created-a-full-stack-resume-builder-using-nextjs-and-prisma-5gbi</link>
      <guid>https://dev.to/shubham_bhilare_3611/how-i-created-a-full-stack-resume-builder-using-nextjs-and-prisma-5gbi</guid>
      <description>&lt;p&gt;🚀 Live Demo: &lt;a href="https://resume-org.vercel.app" rel="noopener noreferrer"&gt;https://resume-org.vercel.app&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Introduction&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Building a resume can be a tedious task, especially when you want a polished, professional look without spending hours on formatting. To solve this, I decided to create a full-stack Resume Builder web app that offers users multiple templates, a dynamic editor, and seamless export to PDF.&lt;/p&gt;

&lt;p&gt;In this post, I’ll share the features, tech stack, challenges, and future plans of this project, along with a live demo you can try out yourself.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Tech Stack Overview&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To build a modern, scalable application, I chose the following technologies:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Next.js — For both frontend and backend with React and API routes&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Prisma ORM — To manage PostgreSQL database schema and queries efficiently&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;PostgreSQL (hosted on NeonDB) — For storing user data and resume information&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;NextAuth.js — Handling authentication with Google, LinkedIn, and Twitter OAuth providers&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Amazon S3 — Storing user assets like profile images securely&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Vercel — Hosting the entire application for fast, global delivery&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;strong&gt;Key Features&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;1. User Authentication&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Users can sign up and log in easily using their Google, LinkedIn, or Twitter accounts — thanks to NextAuth.js, which made integrating OAuth smooth and secure.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;2. Ten Beautiful Resume Templates&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The app offers 10 distinct, professionally designed resume templates. Users can select a template that suits their style and industry.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;3. Dynamic Resume Editor&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;The editor page lets users fill in their personal details, work experience, education, skills, and more — with live preview so they see changes instantly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;4. PDF Export&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Once finished, users can download their resume as a PDF, preserving the chosen template’s formatting perfectly.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;5. User Dashboard and Settings&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Users have access to a personal dashboard where they can manage resumes, update profile information, and reset their passwords securely.&lt;/p&gt;

&lt;p&gt;Challenges and Learnings&lt;/p&gt;

&lt;p&gt;PDF Generation&lt;/p&gt;

&lt;p&gt;Ensuring that the resumes print correctly to PDF across different browsers was tricky. Chrome’s print engine behaves differently than others, so I had to experiment with CSS print styles and React-to-PDF libraries to get consistent results.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;OAuth Integration&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Supporting multiple OAuth providers required careful handling of user sessions and callback URLs. NextAuth.js was very helpful, but I had to tweak adapters to fit Prisma and NeonDB.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Asset Management&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Uploading and serving user profile images securely was a priority. Using Amazon S3 with signed URLs ensured that images were private and scalable.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Final Thoughts&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;This project has been an incredible learning journey into full-stack development, cloud asset management, and authentication flows. If you’re looking to build your own web apps, I highly recommend exploring Next.js and Prisma — the developer experience is excellent.&lt;/p&gt;

&lt;p&gt;Feel free to check out the live demo here: &lt;a href="https://resume-org.vercel.app" rel="noopener noreferrer"&gt;https://resume-org.vercel.app&lt;/a&gt; and share your feedback or questions!&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Thanks for reading!&lt;/em&gt;&lt;br&gt;
&lt;em&gt;— Shubham (SKB)&lt;/em&gt;&lt;/p&gt;

</description>
      <category>webdev</category>
      <category>react</category>
      <category>nextjs</category>
      <category>buildinpublic</category>
    </item>
  </channel>
</rss>
