Skip to content

Commit

Permalink
App router migration new relic configuration (#1086)
Browse files Browse the repository at this point in the history
* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Add new relic nextjs configuration

* Create new relic configuration file

* Use new relic configuration

* Remove non required file

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* App router migration google tag manager script (#1117)

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Remove non required file

* Add google tag manager to root layout

* Change strategy as worker is experimental and is not including the script

* Move gtm to body as next is including it in head properly

* Add comment to tackle in the future

* Move gtm script from _document to _app

* App router migration rollbar script (#1118)

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Remove non required file

* Use script tag and set id

* Add rollbar script to root layout

* Make it beforeInteractive so it is included in the head

* Move to _app as next/script is not working in _document

* App router migration opengraph metadata (#1120)

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Remove non required file

* Move primary color to a constant so can be used in a server component (root layout)

* Create rootMetadata

* Fix format

* Add metadata to root layout

---------

Co-authored-by: eleanorreem <[email protected]>

* App router migration error boundary component (#1121)

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Remove non required file

* Make error boundary client component

* Add ErrorBoundary component to root layout

* Create app router error route test page

---------

Co-authored-by: eleanorreem <[email protected]>

* App router migration material UI configuration (#1122)

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Remove non required file

* Create theme registry component

* Add ThemeRegistry to root layout

* Make theme client component

* Install mui for app router

---------

Co-authored-by: eleanorreem <[email protected]>

* App router migration analytics (#1123)

* Add basic Root Layout

* Add metadata

* Add reference included by next

* Add comment to explain the default meta tags

* Add public testing page to check the migration

* Remove non required file

* Create Analytics component

* Add analytics to root layout

* Update layout.tsx

---------

Co-authored-by: eleanorreem <[email protected]>

---------

Co-authored-by: eleanorreem <[email protected]>
  • Loading branch information
boodland and eleanorreem committed Oct 8, 2024
1 parent df05a53 commit c76bfa0
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
7 changes: 5 additions & 2 deletions app/layout.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,21 @@
import Analytics from '../components/head/Analytics';
import GoogleTagManagerScript from '../components/head/GoogleTagManagerScript';
import RollbarScript from '../components/head/RollbarScript';
import ErrorBoundary from '../components/layout/ErrorBoundary';
import { newRelicInit } from '../config/newRelic';
import rootMetadata from './rootMetadata';
import RollbarScript from '../components/head/RollbarScript';
import ThemeRegistry from './ThemeRegistry';

export const metadata = rootMetadata;

export default function RootLayout({
export default async function RootLayout({
// Layouts must accept a children prop.
// This will be populated with nested layouts or pages
children,
}: {
children: React.ReactNode;
}) {
const NewRelicScript = await newRelicInit();
return (
<html lang="en">
<body>
Expand All @@ -26,6 +28,7 @@ export default function RootLayout({
<ErrorBoundary>
<ThemeRegistry>{children}</ThemeRegistry>
</ErrorBoundary>
{NewRelicScript}
<Analytics />
</body>
</html>
Expand Down
46 changes: 46 additions & 0 deletions config/newRelic.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import newrelic from 'newrelic';
import Script from 'next/script';

// Configuration according to Newrelic app router example
// See https://github.com/newrelic/newrelic-node-nextjs?tab=readme-ov-file#example-projects
export const newRelicInit = async () => {
// @ts-ignore
if (newrelic.agent.collector.isConnected() === false) {
await new Promise((resolve) => {
// @ts-ignore
newrelic.agent.on('connected', resolve);
});
}

const browserTimingHeader = newrelic.getBrowserTimingHeader({
hasToRemoveScriptWrapper: true,
// @ts-ignore
allowTransactionlessInjection: true,
});

return <NewRelicScript browserTimingHeader={browserTimingHeader} />;
};

export type NewRelicScriptProps = {
browserTimingHeader: string;
};

const NewRelicScript = ({ browserTimingHeader }: NewRelicScriptProps) => {
return (
// eslint-disable-next-line @next/next/no-before-interactive-script-outside-document
<Script
// We have to set an id for inline scripts.
// See https://nextjs.org/docs/app/building-your-application/optimizing/scripts#inline-scripts
id="nr-browser-agent"
// By setting the strategy to "beforeInteractive" we guarantee that
// the script will be added to the document's `head` element.
strategy="beforeInteractive"
// The body of the script element comes from the async evaluation
// of `getInitialProps`. We use the special
// `dangerouslySetInnerHTML` to provide that element body. Since
// it requires an object with an `__html` property, we pass in an
// object literal.
dangerouslySetInnerHTML={{ __html: browserTimingHeader }}
/>
);
};
18 changes: 18 additions & 0 deletions next.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,26 @@ const withBundleAnalyzer = require('@next/bundle-analyzer')({
enabled: process.env.ANALYZE === 'true',
});

// Configuration according to Newrelic app router example
// See https://github.com/newrelic/newrelic-node-nextjs?tab=readme-ov-file#example-projects
const nrExternals = require('@newrelic/next/load-externals');

module.exports = withBundleAnalyzer(
withPWA({
experimental: {
// Without this setting, the Next.js compilation step will routinely
// try to import files such as `LICENSE` from the `newrelic` module.
// See https://nextjs.org/docs/app/api-reference/next-config-js/serverComponentsExternalPackages.
serverComponentsExternalPackages: ['newrelic'],
},

// In order for newrelic to effectively instrument a Next.js application,
// the modules that newrelic supports should not be mangled by webpack. Thus,
// we need to "externalize" all of the modules that newrelic supports.
webpack: (config) => {
nrExternals(config);
return config;
},
reactStrictMode: true,
publicRuntimeConfig: {
NEXT_PUBLIC_API_URL: process.env.NEXT_PUBLIC_API_URL,
Expand Down

0 comments on commit c76bfa0

Please sign in to comment.