# Integrate JavaScript SDK v3 with your Next.js App

<p>This guide will help you integrate RudderStack with your Next.js app using the <a href="https://www.rudderstack.com/docs/sources/event-streams/sdks/rudderstack-javascript-sdk/" >JavaScript SDK v3</a>. On successful integration, you can track and send real-time user events to your preferred destinations via RudderStack.</p>
<p>To set up the event stream on your Next.js app, you need to perform the following steps:</p>
<ol>
<li><a href="#integrate-javascript-sdk-with-your-nextjs-app" >Integrate JavaScript SDK with your Next.js app and set up the tracking code</a>.</li>
<li><a href="#configure-a-destination-in-rudderstack" >Configure a destination in RudderStack</a>.</li>
<li><a href="#deploy-your-app-and-verify-events" >Deploy your Next.js app and verify the events</a>.</li>
</ol>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="prerequisites">Prerequisites</h2><p>This guide assumes you have installed and set up your Next.js app. Refer to the <a href="https://nextjs.org/docs/getting-started" >Next.js documentation</a> for more information.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="integrate-javascript-sdk-with-your-nextjs-app">Integrate JavaScript SDK with your Next.js app</h2><p>Integrating the JavaScript SDK with your Next.js app involves the following steps:</p>
<ol>
<li><a href="#create-a-javascript-source" >Creating a JavaScript source in RudderStack</a>.</li>
<li><a href="#install-and-configure-the-sdk-in-your-app" >Installing and configuring the JavaScript SDK in your Next.js app</a>.</li>
</ol>
<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="create-a-javascript-source">Create a JavaScript source</h3><p>The RudderStack JavaScript source is required track the events from your Next.js app. Follow these steps to set it up in your <a href="https://app.rudderstack.com/" >RudderStack dashboard</a>:</p>
<ol>
<li>Note the data plane URL in your RudderStack dashboard. This is required to set up the JavaScript SDK in your Next.js app.</li>
</ol>

<figure class="image--main "  >
    <a 
         href="/docs/images/rs-cloud/data-plane-url.webp"
        
        >
        <img src="/docs/images/rs-cloud/data-plane-url.webp" 
         alt="Data Plane URL"  
         
         
        decoding="async" loading="lazy" class="img-shortcode"/>
    </a>
    
</figure>

<ol start="2">
<li>Click the <strong>Sources</strong> button in the left navigation bar and select <strong>New Source</strong> to create a source. Under <strong>Sources</strong>, select <strong>Event Streams</strong> &gt; <strong>JavaScript</strong>.</li>
<li>Assign a name to your source and click <strong>Continue</strong>.</li>
<li>Your JavaScript source is now configured. Note down the write key for this source:</li>
</ol>

<figure class="image--main "  >
    <a 
         href="/docs/images/user-guides/jamstack-guides/js-write-key.webp"
        
        >
        <img src="/docs/images/user-guides/jamstack-guides/js-write-key.webp" 
         alt="JavaScript source write key"  
         
         
        decoding="async" loading="lazy" class="img-shortcode"/>
    </a>
    
</figure>

<!-- end-chunk -->
<!-- begin-chunk -->
<h3 id="install-and-configure-the-sdk-in-your-app">Install and configure the SDK in your app</h3><p>You can integrate RudderStack with your Next.js app and set up the tracking code by following the steps below:</p>
<ol>
<li>In your Next.js project folder, create a <code>useRudderAnalytics.ts</code> file with the following code:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">import { useEffect, useState } from &#39;react&#39;;
import type { RudderAnalytics } from &#39;@rudderstack/analytics-js&#39;;

const useRudderStackAnalytics = (): RudderAnalytics | undefined =&gt; {
  const [analytics, setAnalytics] = useState&lt;RudderAnalytics&gt;();

  useEffect(() =&gt; {
    if (!analytics) {
      const initialize = async () =&gt; {
        const { RudderAnalytics } = await import(&#39;@rudderstack/analytics-js&#39;);
        const analyticsInstance = new RudderAnalytics();

        analyticsInstance.load(&#39;WRITE_KEY&#39;, &#39;DATA_PLANE_URL&#39;);

        analyticsInstance.ready(() =&gt; {
          console.log(&#39;We are all set!!!&#39;);
        });
        
        setAnalytics(analyticsInstance);
      };

      initialize().catch(e =&gt; console.log(e));
    }
  }, [analytics]);

  return analytics;
};

export default useRudderStackAnalytics;</code></pre></div>
</div>
<ol start="2">
<li>Replace <code>WRITE_KEY</code> and <code>DATA_PLANE_URL</code> with your JavaScript source write key and the data plane URL obtained in the <a href="#create-a-javascript-source" >Creating a JavaScript source in RudderStack</a> section above.</li>
<li>To buffer the events triggered before the SDK is loaded, add the following script in the <code>layout.tsx</code> file within the <code>src</code> folder:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">import Script from &#39;next/script&#39;;

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    &lt;html lang=&#39;en&#39;&gt;
      &lt;head&gt;
        &lt;Script id=&#39;bufferEvents&#39;&gt;
          {`
            window.rudderanalytics = [];
            var methods = [
              &#39;setDefaultInstanceKey&#39;,
              &#39;load&#39;,
              &#39;ready&#39;,
              &#39;page&#39;,
              &#39;track&#39;,
              &#39;identify&#39;,
              &#39;alias&#39;,
              &#39;group&#39;,
              &#39;reset&#39;,
              &#39;setAnonymousId&#39;,
              &#39;startSession&#39;,
              &#39;endSession&#39;,
              &#39;consent&#39;
            ];
            for (var i = 0; i &lt; methods.length; i++) {
              var method = methods[i];
              window.rudderanalytics[method] = (function (methodName) {
                return function () {
                  window.rudderanalytics.push([methodName].concat(Array.prototype.slice.call(arguments)));
                };
              })(method);
            }
            // Below line is only for demonstration purpose, SPA code is better place for auto page call
            window.rudderanalytics.page(&#39;sample page call&#39;);
        `}
        &lt;/Script&gt;
      &lt;/head&gt;
      &lt;body className={inter.className}&gt;{children}&lt;/body&gt;
    &lt;/html&gt;
  );
}</code></pre></div>
</div>
<ol start="4">
<li>If you are using an app router, go to the <code>app</code> folder and open the <code>page.tsx</code> file. If you are using a page router, go to the <code>pages</code> folder and open the <code>index.tsx</code> file. Then, add the following code:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">javascript<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-javascript" data-lang="javascript">import { useEffect } from &#34;react&#34;;
import useRudderStackAnalytics from &#39;./useRudderAnalytics&#39;;

export default function Home() {
  const analytics = useRudderStackAnalytics();

  const page = () =&gt; {
    analytics?.page(&#39;Cart Viewed&#39;);
  };
  const identify = () =&gt; {
    analytics?.identify(&#39;sample-user-123&#39;);
  };
  const track = () =&gt; {
    analytics?.track(&#39;Order Completed&#39;);
  };

  useEffect(() =&gt; {
    if(analytics) {
      analytics.page(&#39;Auto track&#39;);
    }
  }, [analytics])

return (
    &lt;main className=&#39;flex min-h-screen flex-col items-center justify-between p-24&#39;&gt;
      &lt;div className=&#39;mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left&#39;&gt;
        &lt;button
          onClick={page}
          className=&#39;group rounded-lg border border-transparent px-5 py-4 transition-colors hover:border-gray-300 hover:bg-gray-100 hover:dark:border-neutral-700 hover:dark:bg-neutral-800/30&#39;&gt;
          &lt;h2 className={`mb-3 text-2xl font-semibold`}&gt;Page &lt;/h2&gt;
          &lt;p className={`m-0 max-w-[30ch] text-sm opacity-50`}&gt;
            Clicking this tile will trigger a page event.
          &lt;/p&gt;
        &lt;/button&gt;
     &lt;/div&gt;
	&lt;/main&gt;
 );
}</code></pre></div>
</div>
<p>See the <a href="https://github.com/rudderlabs/rudder-sdk-js/tree/develop/examples/nextjs/hooks/sample-app" >sample Next.js app</a> for more information.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="configure-a-destination-in-rudderstack">Configure a destination in RudderStack</h2><p>This section details the steps required to set up a destination in RudderStack, where you can send all events tracked by the JavaScript SDK you set up above.</p>
<ol>
<li>In your RudderStack dashboard, click <strong>Destinations</strong> &gt; <strong>New destination</strong>.</li>
<li>Choose your preferred destination from the list.</li>
<li>Assign a name to the destination and click <strong>Continue</strong>.</li>
<li>Select the JavaScript source configured in the above section and click <strong>Continue</strong>.</li>
<li>Configure the destination with the required settings.</li>
</ol>
<p>Optionally, you can add a <a href="https://www.rudderstack.com/docs/transformations/overview/" >user transformation</a> to this destination to transform your events.</p>
<!-- end-chunk -->
<!-- begin-chunk -->
<h2 id="deploy-your-app-and-verify-events">Deploy your app and verify events</h2><p>To verify if your event stream is working correctly, deploy your Next.js app and test if the events are tracked and delivered correctly. To do so, follow these steps:</p>
<ol>
<li>From your terminal, navigate to the folder containing your Next.js app and run following command:</li>
</ol>
<div class="rs-code">
  <div class="rs-code__head">bash<button class="rs-code__copy" type="button">
      
      Copy
    </button>
  </div>
  <div class="highlight"><pre class="chroma"><code class="language-bash" data-lang="bash">npm run dev</code></pre></div>
</div>
<ol start="2">
<li>Open the local server URL(generally <code>http://localhost:3000/</code>) in your browser to view the app.</li>
<li>Go to your browser&rsquo;s developer tools and open the <strong>Network</strong> tab. Click the buttons in your app to trigger the RudderStack events.</li>
<li>Verify in the <strong>Network</strong> tab if the events are sent successfully:</li>
</ol>

<figure class="image--main "  >
    <a 
         href="/docs/images/user-guides/jamstack-guides/angular-network-tab.webp"
        
        >
        <img src="/docs/images/user-guides/jamstack-guides/angular-network-tab.webp" 
         alt="Verifying events"  
         
         
        decoding="async" loading="lazy" class="img-shortcode"/>
    </a>
    
</figure>

<ol start="5">
<li>Go to the <strong>Live Events</strong> tab of your JavaScript source in the RudderStack dashboard to check if the events are tracked. Note that you may face a minor delay before the events start showing up in your dashboard.</li>
<li>Go to your destination to verify if the events are received successfully.</li>
</ol>
<br />

