# Next.js Quickstart Guide

[Next.js](https://nextjs.org/) is a popular front-end framework for building React-based applications optimized for server-side rendering (SSR) and static website generation. While we usually recommend using React's [`useEffect`](https://react.dev/reference/react/useEffect) [hook as a way to initialize the Freshpaint SDK](https://documentation.freshpaint.io/readme/guides/quickstart/installing-the-freshpaint-javascript-sdk-with-server-side-rendering-ssr-+-react), **Next.js requires its own special approach to integrating Freshpaint with your application.** Next.js provides a built in component called [`Script`](https://nextjs.org/docs/pages/api-reference/components/script) that is used to add additional JavaScript to the page.

Below is an example of a Next.js component you might create to add the Freshpaint SDK to the page and initialize it for your site's Freshpaint environment.

```tsx
import React from 'react'
import Script from 'next/script';

export default function FreshpaintSnippet() {
  return (
    <>
      <Script
        id="freshpaint-snippet"
        dangerouslySetInnerHTML={{
          __html: `
            (function(){function p(r,e){(e==null||e>r.length)&&(e=r.length);for(var t=0,a=new Array(e);t<e;t++)a[t]=r[t];return a}function v(r){if(Array.isArray(r))return p(r)}function h(r){if(typeof Symbol!="undefined"&&r[Symbol.iterator]!=null||r["@@iterator"]!=null)return Array.from(r)}function A(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function I(r,e){if(r){if(typeof r=="string")return p(r,e);var t=Object.prototype.toString.call(r).slice(8,-1);if(t==="Object"&&r.constructor&&(t=r.constructor.name),t==="Map"||t==="Set")return Array.from(t);if(t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return p(r,e)}}function y(r){return v(r)||h(r)||I(r)||A()}var E=function(r,e){if(!e.__SV){try{var t,a,m=window.location,c=m.hash,x=function(n,o){return t=n.match(new RegExp(o+"=([^&]*)")),t?t[1]:null};c&&x(c,"fpState")&&(a=JSON.parse(decodeURIComponent(x(c,"fpState"))),a.action==="fpeditor"&&(window.sessionStorage.setItem("_fpcehash",c),history.replaceState(a.desiredHash||"",r.title,m.pathname+m.search)))}catch(S){}e.__loaded=!1,e.config=!1,e.__SV=2,window.freshpaint=new Proxy(e,{get:function(n,o){return n[o]!==void 0?n[o]:o==="init"?function(l,u,i){var _,d;(_=n)[d="_i"]||(_[d]=[]),n._i.push([l,u||{},i||"freshpaint"])}:function(){for(var l=arguments.length,u=new Array(l),i=0;i<l;i++)u[i]=arguments[i];var _=[o].concat(y(u));return n.push(_),new Proxy(_,{get:function(f,w){return f[w]?f[w]:function(){for(var b=arguments.length,g=new Array(b),s=0;s<b;s++)g[s]=arguments[s];f.length=0,f.push([o].concat(y(u))),f.push([w].concat(y(g)))}}})}}})}};E(document,window.freshpaint||[]);})();
            freshpaint.init("YOUR FRESHPAINT ENVIRONMENT ID HERE");
            freshpaint.page();
          `
        }}
      />
      <Script src="https://freshpaint-cdn.com/js/YOUR FRESHPAINT ENVIRONMENT ID HERE/freshpaint.js" />
    </>
  )
}
```

### Finding your Freshpaint Web snippet

The contents of each `Script` component's JavaScript source correspond to the two `script`  tags found in the Freshpaint application under the **Web** integration of the **Sources** page at <https://app.freshpaint.io/sources>. You should see the modal containing your Freshpaint snippets below by clicking the **Configure** button next to the **Web** integration:

![](https://1666823438-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2F-MA7aDqsXMFbUsWVqonF%2Fuploads%2FSOlGqA3G7L4xRQFdroqy%2Fimage.png?alt=media\&token=c39fb3d0-bb4b-41eb-8693-0dc4d5849d1a):

Let's take a look at each `Script` component in more detail.

### The first Script component

```tsx
      <Script
        id="freshpaint-snippet"
        dangerouslySetInnerHTML={{
          __html: `
            (function(){function p(r,e){(e==null||e>r.length)&&(e=r.length);for(var t=0,a=new Array(e);t<e;t++)a[t]=r[t];return a}function v(r){if(Array.isArray(r))return p(r)}function h(r){if(typeof Symbol!="undefined"&&r[Symbol.iterator]!=null||r["@@iterator"]!=null)return Array.from(r)}function A(){throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}function I(r,e){if(r){if(typeof r=="string")return p(r,e);var t=Object.prototype.toString.call(r).slice(8,-1);if(t==="Object"&&r.constructor&&(t=r.constructor.name),t==="Map"||t==="Set")return Array.from(t);if(t==="Arguments"||/^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t))return p(r,e)}}function y(r){return v(r)||h(r)||I(r)||A()}var E=function(r,e){if(!e.__SV){try{var t,a,m=window.location,c=m.hash,x=function(n,o){return t=n.match(new RegExp(o+"=([^&]*)")),t?t[1]:null};c&&x(c,"fpState")&&(a=JSON.parse(decodeURIComponent(x(c,"fpState"))),a.action==="fpeditor"&&(window.sessionStorage.setItem("_fpcehash",c),history.replaceState(a.desiredHash||"",r.title,m.pathname+m.search)))}catch(S){}e.__loaded=!1,e.config=!1,e.__SV=2,window.freshpaint=new Proxy(e,{get:function(n,o){return n[o]!==void 0?n[o]:o==="init"?function(l,u,i){var _,d;(_=n)[d="_i"]||(_[d]=[]),n._i.push([l,u||{},i||"freshpaint"])}:function(){for(var l=arguments.length,u=new Array(l),i=0;i<l;i++)u[i]=arguments[i];var _=[o].concat(y(u));return n.push(_),new Proxy(_,{get:function(f,w){return f[w]?f[w]:function(){for(var b=arguments.length,g=new Array(b),s=0;s<b;s++)g[s]=arguments[s];f.length=0,f.push([o].concat(y(u))),f.push([w].concat(y(g)))}}})}}})}};E(document,window.freshpaint||[]);})();
            freshpaint.init("YOUR FRESHPAINT ENVIRONMENT ID HERE");
            freshpaint.page();
          `
        }}
      />
```

In the code above, there are a few important things to note:

1. Next.js requires that a unique `id` attribute be defined on any `Script` component that does NOT use the `src` attribute to reference a remote JavaScript source file. This must be defined or Next.js will not be able to properly render the `script` HTML element onto the page.
2. The value of the prop `dangerouslySetInnerHTML.__html` comes from the first `script` tag in your Freshpaint environment's **Web** integration snippet (described in the section above).

### The second Script component

```tsx
<Script src="https://freshpaint-cdn.com/js/YOUR FRESHPAINT ENVIRONMENT ID HERE/freshpaint.js" />
```

In the code above, the value of the `src` attribute comes from the second `script` tag in your Freshpaint environment's **Web** integration snippet (described in the section above).

### Rendering the FreshpaintSnippet component in your Next.js application

The best location to render your new `FreshpaintSnippet` component in your Next.js application will depend upon what kind of Next.js application you are building, and the structure of your application. In general, we recommend rendering the `FreshpaintSnippet` component in one of the "root" components of your application. Your `FreshpaintSnippet` should only render onto the page one time, and should remain rendered on the page for the lifetime of your Next.js application.
