diff --git a/examples/with-axiom/.gitignore b/examples/with-axiom/.gitignore
new file mode 100644
index 000000000000..88b6f0d98164
--- /dev/null
+++ b/examples/with-axiom/.gitignore
@@ -0,0 +1,37 @@
+# See https://help.github.com/articles/ignoring-files/ for more about ignoring files.
+
+# dependencies
+/node_modules
+/.pnp
+.pnp.js
+
+# testing
+/coverage
+
+# next.js
+/.next/
+/out/
+
+# production
+/build
+
+# misc
+.DS_Store
+*.pem
+
+# debug
+npm-debug.log*
+yarn-debug.log*
+yarn-error.log*
+
+# local env files
+.env.local
+.env.development.local
+.env.test.local
+.env.production.local
+
+# vercel
+.vercel
+
+# typescript
+*.tsbuildinfo
diff --git a/examples/with-axiom/README.md b/examples/with-axiom/README.md
new file mode 100644
index 000000000000..0671cfa9c5fa
--- /dev/null
+++ b/examples/with-axiom/README.md
@@ -0,0 +1,25 @@
+# Example app with Axiom
+
+This example shows how to use a [Next.js](https://nextjs.org/) project along with [Axiom](https://axiom.co) via the [next-axiom](https://github.com/axiomhq/next-axiom) package. A custom `withAxiom` wrapper is used to wrap the next config object, middleware and API functions. The `log` object could be used from frontend, middleware and API functions.
+
+## Deploy your own
+
+Deploy the example using [Vercel](https://vercel.com?utm_source=github&utm_medium=readme&utm_campaign=next-example) or preview live with [StackBlitz](https://stackblitz.com/github/vercel/next.js/tree/canary/examples/with-axiom)
+
+[![Deploy with Vercel](https://vercel.com/button)](https://vercel.com/new/git/external?repository-url=https://github.com/vercel/next.js/tree/canary/examples/with-axiom&project-name=with-axiom&repository-name=with-axiom)
+
+Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
+
+## How to use
+
+Execute [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app) with [npm](https://docs.npmjs.com/cli/init), [Yarn](https://yarnpkg.com/lang/en/docs/cli/create/), or [pnpm](https://pnpm.io) to bootstrap the example::
+
+```bash
+npx create-next-app --example with-axiom with-axiom-app
+# or
+yarn create next-app --example with-axiom with-axiom-app
+# or
+pnpm create next-app --example with-axiom with-axiom-app
+```
+
+Deploy it to the cloud with [Vercel](https://vercel.com/new?utm_source=github&utm_medium=readme&utm_campaign=next-example) ([Documentation](https://nextjs.org/docs/deployment)) and watch data coming into your Axiom dataset.
diff --git a/examples/with-axiom/middleware.ts b/examples/with-axiom/middleware.ts
new file mode 100644
index 000000000000..9c2833a5b8ec
--- /dev/null
+++ b/examples/with-axiom/middleware.ts
@@ -0,0 +1,9 @@
+import { NextResponse } from 'next/server'
+import { log, withAxiom } from 'next-axiom'
+
+async function middleware() {
+ log.info('Hello from middleware', { bar: 'baz' })
+ return NextResponse.next()
+}
+
+export default withAxiom(middleware)
diff --git a/examples/with-axiom/next-env.d.ts b/examples/with-axiom/next-env.d.ts
new file mode 100644
index 000000000000..4f11a03dc6cc
--- /dev/null
+++ b/examples/with-axiom/next-env.d.ts
@@ -0,0 +1,5 @@
+///
+///
+
+// NOTE: This file should not be edited
+// see https://nextjs.org/docs/basic-features/typescript for more information.
diff --git a/examples/with-axiom/next.config.js b/examples/with-axiom/next.config.js
new file mode 100644
index 000000000000..4ddf957b071a
--- /dev/null
+++ b/examples/with-axiom/next.config.js
@@ -0,0 +1,8 @@
+const { withAxiom } = require('next-axiom')
+
+/** @type {import('next').NextConfig} */
+const nextConfig = withAxiom({
+ reactStrictMode: true,
+})
+
+module.exports = nextConfig
diff --git a/examples/with-axiom/package.json b/examples/with-axiom/package.json
new file mode 100644
index 000000000000..5c1b7401446c
--- /dev/null
+++ b/examples/with-axiom/package.json
@@ -0,0 +1,21 @@
+{
+ "private": true,
+ "scripts": {
+ "dev": "next dev",
+ "build": "next build",
+ "start": "next start"
+ },
+ "dependencies": {
+ "next": "latest",
+ "next-axiom": "^0.10.0",
+ "react": "^18.2.0",
+ "react-dom": "^18.2.0",
+ "swr": "^1.3.0"
+ },
+ "devDependencies": {
+ "@types/react": "^18.0.5",
+ "@types/react-dom": "^18.0.1",
+ "@types/node": "^16.11.26",
+ "typescript": "^4.7.4"
+ }
+}
diff --git a/examples/with-axiom/pages/_app.tsx b/examples/with-axiom/pages/_app.tsx
new file mode 100644
index 000000000000..27fd9af82530
--- /dev/null
+++ b/examples/with-axiom/pages/_app.tsx
@@ -0,0 +1,11 @@
+import { log } from 'next-axiom'
+import { AppProps } from 'next/app'
+export { reportWebVitals } from 'next-axiom'
+
+log.info('Hello from frontend', { foo: 'bar' })
+
+const MyApp = ({ Component, pageProps }: AppProps) => {
+ return
+}
+
+export default MyApp
diff --git a/examples/with-axiom/pages/api/hello.ts b/examples/with-axiom/pages/api/hello.ts
new file mode 100644
index 000000000000..3515f82ab103
--- /dev/null
+++ b/examples/with-axiom/pages/api/hello.ts
@@ -0,0 +1,10 @@
+// Next.js API route support: https://nextjs.org/docs/api-routes/introduction
+import type { NextApiRequest, NextApiResponse } from 'next'
+import { log, withAxiom } from 'next-axiom'
+
+async function handler(req: NextApiRequest, res: NextApiResponse) {
+ log.info('Hello from function', { url: req.url })
+ res.status(200).json({ name: 'John Doe' })
+}
+
+export default withAxiom(handler)
diff --git a/examples/with-axiom/pages/index.tsx b/examples/with-axiom/pages/index.tsx
new file mode 100644
index 000000000000..230ac54de96a
--- /dev/null
+++ b/examples/with-axiom/pages/index.tsx
@@ -0,0 +1,31 @@
+import { GetStaticPropsContext } from 'next'
+import { log } from 'next-axiom'
+import useSWR from 'swr'
+
+export const getStaticProps = async (ctx: GetStaticPropsContext) => {
+ log.info('Hello from SSR', { ctx })
+ return {
+ props: {},
+ }
+}
+
+const fetcher = async (...args: any[]) => {
+ log.info('Hello from SWR', { args })
+ const res = await fetch.apply(null, [...args])
+ return await res.json()
+}
+
+const Home = () => {
+ const { data, error } = useSWR('/api/hello', fetcher)
+
+ if (error) return
Failed to load
+ if (!data) return Loading...
+
+ return (
+
+
{data.name}
+
+ )
+}
+
+export default Home
diff --git a/examples/with-axiom/tsconfig.json b/examples/with-axiom/tsconfig.json
new file mode 100644
index 000000000000..b9cc80c0d4ec
--- /dev/null
+++ b/examples/with-axiom/tsconfig.json
@@ -0,0 +1,19 @@
+{
+ "compilerOptions": {
+ "target": "es5",
+ "lib": ["dom", "dom.iterable", "esnext"],
+ "allowJs": true,
+ "skipLibCheck": true,
+ "strict": false,
+ "forceConsistentCasingInFileNames": true,
+ "noEmit": true,
+ "incremental": true,
+ "esModuleInterop": true,
+ "module": "esnext",
+ "resolveJsonModule": true,
+ "isolatedModules": true,
+ "jsx": "preserve"
+ },
+ "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
+ "exclude": ["node_modules"]
+}
diff --git a/packages/next/lib/eslint/hasEslintConfiguration.ts b/packages/next/lib/eslint/hasEslintConfiguration.ts
index 113e72926192..6c600f545478 100644
--- a/packages/next/lib/eslint/hasEslintConfiguration.ts
+++ b/packages/next/lib/eslint/hasEslintConfiguration.ts
@@ -33,12 +33,10 @@ export async function hasEslintConfiguration(
}
return { ...configObject, exists: true }
} else if (packageJsonConfig?.eslintConfig) {
- if (Object.entries(packageJsonConfig?.eslintConfig).length === 0) {
- return {
- ...configObject,
- emptyPkgJsonConfig: true,
- }
+ if (Object.keys(packageJsonConfig?.eslintConfig).length) {
+ return { ...configObject, exists: true }
}
+ return { ...configObject, emptyPkgJsonConfig: true }
}
return configObject
}
diff --git a/test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts b/test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts
index d24e7755b4ed..ab31e1f3100b 100644
--- a/test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts
+++ b/test/e2e/no-eslint-warn-with-no-eslint-config/index.test.ts
@@ -65,5 +65,23 @@ describe('no-eslint-warn-with-no-eslint-config', () => {
await next.patchFile('package.json', origPkgJson)
}
})
+
+ it('should not warn with eslint config in package.json', async () => {
+ await next.stop()
+ const origPkgJson = await next.readFile('package.json')
+ const pkgJson = JSON.parse(origPkgJson)
+ pkgJson.eslintConfig = { rules: { semi: 'off' } }
+
+ try {
+ await next.patchFile('package.json', JSON.stringify(pkgJson))
+ await next.start()
+
+ expect(next.cliOutput).not.toContain(
+ 'No ESLint configuration detected. Run next lint to begin setup'
+ )
+ } finally {
+ await next.patchFile('package.json', origPkgJson)
+ }
+ })
}
})