Skip to content
Snippets Groups Projects
Commit 24cd04d1 authored by Marcus Schiesser's avatar Marcus Schiesser
Browse files

add llama nextjs simple template

parent abb065d1
No related branches found
No related tags found
No related merge requests found
Showing
with 585 additions and 185 deletions
# Create Next App # Create Next App
The easiest way to get started with Next.js is by using `create-next-app`. This CLI tool enables you to quickly start building a new Next.js application, with everything set up for you. You can create a new app using the default Next.js template, or by using one of the [official Next.js examples](https://github.com/vercel/next.js/tree/canary/examples). To get started, use the following command: The easiest way to get started with LlamaIndex is by using `create-llama`. This CLI tool enables you to quickly start building a new LlamaIndex application, with everything set up for you. You can create a new app using the default LlamaIndex template, or by using one of the [official LlamaIndex examples](https://github.com/vercel/next.js/tree/canary/examples). To get started, use the following command:
### Interactive ### Interactive
You can create a new project interactively by running: You can create a new project interactively by running:
```bash ```bash
npx create-next-app@latest npx create-llama@latest
# or # or
yarn create next-app yarn create next-app
# or # or
pnpm create next-app pnpm create next-app
# or # or
bunx create-next-app bunx create-llama
``` ```
You will be asked for the name of your project, and then whether you want to You will be asked for the name of your project, and then whether you want to
...@@ -28,20 +28,14 @@ Select **Yes** to install the necessary types/dependencies and create a new TS p ...@@ -28,20 +28,14 @@ Select **Yes** to install the necessary types/dependencies and create a new TS p
### Non-interactive ### Non-interactive
You can also pass command line arguments to set up a new project You can also pass command line arguments to set up a new project
non-interactively. See `create-next-app --help`: non-interactively. See `create-llama --help`:
```bash ```bash
create-next-app <project-directory> [options] create-llama <project-directory> [options]
Options: Options:
-V, --version output the version number -V, --version output the version number
--ts, --typescript
Initialize as a TypeScript project. (default)
--js, --javascript
Initialize as a JavaScript project.
--use-npm --use-npm
...@@ -62,7 +56,7 @@ Options: ...@@ -62,7 +56,7 @@ Options:
-e, --example [name]|[github-url] -e, --example [name]|[github-url]
An example to bootstrap the app with. You can use an example name An example to bootstrap the app with. You can use an example name
from the official Next.js repo or a GitHub URL. The URL can use from the official LlamaIndex repo or a GitHub URL. The URL can use
any branch and/or subdirectory any branch and/or subdirectory
--example-path <path-to-example> --example-path <path-to-example>
...@@ -75,10 +69,10 @@ Options: ...@@ -75,10 +69,10 @@ Options:
### Why use Create Next App? ### Why use Create Next App?
`create-next-app` allows you to create a new Next.js app within seconds. It is officially maintained by the creators of Next.js, and includes a number of benefits: `create-llama` allows you to create a new LlamaIndex app within seconds. It is officially maintained by the creators of LlamaIndex, and includes a number of benefits:
- **Interactive Experience**: Running `npx create-next-app@latest` (with no arguments) launches an interactive experience that guides you through setting up a project. - **Interactive Experience**: Running `npx create-llama@latest` (with no arguments) launches an interactive experience that guides you through setting up a project.
- **Zero Dependencies**: Initializing a project is as quick as one second. Create Next App has zero dependencies. - **Zero Dependencies**: Initializing a project is as quick as one second. Create Next App has zero dependencies.
- **Offline Support**: Create Next App will automatically detect if you're offline and bootstrap your project using your local package cache. - **Offline Support**: Create Next App will automatically detect if you're offline and bootstrap your project using your local package cache.
- **Support for Examples**: Create Next App can bootstrap your application using an example from the Next.js examples collection (e.g. `npx create-next-app --example api-routes`). - **Support for Examples**: Create Next App can bootstrap your application using an example from the LlamaIndex examples collection (e.g. `npx create-llama --example api-routes`).
- **Tested**: The package is part of the Next.js monorepo and tested using the same integration test suite as Next.js itself, ensuring it works as expected with every release. - **Tested**: The package is part of the LlamaIndex monorepo and tested using the same integration test suite as LlamaIndex itself, ensuring it works as expected with every release.
...@@ -29,10 +29,8 @@ export async function createApp({ ...@@ -29,10 +29,8 @@ export async function createApp({
packageManager, packageManager,
example, example,
examplePath, examplePath,
typescript,
tailwind, tailwind,
eslint, eslint,
appRouter,
srcDir, srcDir,
importAlias, importAlias,
}: { }: {
...@@ -40,22 +38,14 @@ export async function createApp({ ...@@ -40,22 +38,14 @@ export async function createApp({
packageManager: PackageManager packageManager: PackageManager
example?: string example?: string
examplePath?: string examplePath?: string
typescript: boolean
tailwind: boolean tailwind: boolean
eslint: boolean eslint: boolean
appRouter: boolean
srcDir: boolean srcDir: boolean
importAlias: string importAlias: string
}): Promise<void> { }): Promise<void> {
let repoInfo: RepoInfo | undefined let repoInfo: RepoInfo | undefined
const mode: TemplateMode = typescript ? 'ts' : 'js' const mode: TemplateMode = 'nextjs';
const template: TemplateType = appRouter const template: TemplateType = 'simple';
? tailwind
? 'app-tw'
: 'app'
: tailwind
? 'default-tw'
: 'default'
if (example) { if (example) {
let repoUrl: URL | undefined let repoUrl: URL | undefined
...@@ -141,7 +131,7 @@ export async function createApp({ ...@@ -141,7 +131,7 @@ export async function createApp({
const isOnline = !useYarn || (await getOnline()) const isOnline = !useYarn || (await getOnline())
const originalDirectory = process.cwd() const originalDirectory = process.cwd()
console.log(`Creating a new Next.js app in ${green(root)}.`) console.log(`Creating a new LlamaIndex app in ${green(root)}.`)
console.log() console.log()
process.chdir(root) process.chdir(root)
...@@ -201,7 +191,7 @@ export async function createApp({ ...@@ -201,7 +191,7 @@ export async function createApp({
const tsconfigPath = path.join(root, 'tsconfig.json') const tsconfigPath = path.join(root, 'tsconfig.json')
if (fs.existsSync(tsconfigPath)) { if (fs.existsSync(tsconfigPath)) {
fs.copyFileSync( fs.copyFileSync(
getTemplateFile({ template, mode: 'ts', file: 'next-env.d.ts' }), getTemplateFile({ template, mode: 'nextjs', file: 'next-env.d.ts' }),
path.join(root, 'next-env.d.ts') path.join(root, 'next-env.d.ts')
) )
} }
......
...@@ -29,7 +29,7 @@ export async function getRepoInfo( ...@@ -29,7 +29,7 @@ export async function getRepoInfo(
const filePath = examplePath ? examplePath.replace(/^\//, '') : file.join('/') const filePath = examplePath ? examplePath.replace(/^\//, '') : file.join('/')
if ( if (
// Support repos whose entire purpose is to be a Next.js example, e.g. // Support repos whose entire purpose is to be a LlamaIndex example, e.g.
// https://github.com/:username/:my-cool-nextjs-example-repo-name. // https://github.com/:username/:my-cool-nextjs-example-repo-name.
t === undefined || t === undefined ||
// Support GitHub URL that ends with a trailing slash, e.g. // Support GitHub URL that ends with a trailing slash, e.g.
......
...@@ -38,46 +38,11 @@ const program = new Commander.Command(packageJson.name) ...@@ -38,46 +38,11 @@ const program = new Commander.Command(packageJson.name)
.action((name) => { .action((name) => {
projectPath = name projectPath = name
}) })
.option(
'--ts, --typescript',
`
Initialize as a TypeScript project. (default)
`
)
.option(
'--js, --javascript',
`
Initialize as a JavaScript project.
`
)
.option(
'--tailwind',
`
Initialize with Tailwind CSS config. (default)
`
)
.option( .option(
'--eslint', '--eslint',
` `
Initialize with eslint config. Initialize with eslint config.
`
)
.option(
'--app',
`
Initialize as an App Router project.
`
)
.option(
'--src-dir',
`
Initialize inside a \`src/\` directory.
` `
) )
.option( .option(
...@@ -120,7 +85,7 @@ const program = new Commander.Command(packageJson.name) ...@@ -120,7 +85,7 @@ const program = new Commander.Command(packageJson.name)
` `
An example to bootstrap the app with. You can use an example name An example to bootstrap the app with. You can use an example name
from the official Next.js repo or a GitHub URL. The URL can use from the official LlamaIndex repo or a GitHub URL. The URL can use
any branch and/or subdirectory any branch and/or subdirectory
` `
) )
...@@ -155,7 +120,7 @@ const packageManager = !!program.useNpm ...@@ -155,7 +120,7 @@ const packageManager = !!program.useNpm
: getPkgManager() : getPkgManager()
async function run(): Promise<void> { async function run(): Promise<void> {
const conf = new Conf({ projectName: 'create-next-app' }) const conf = new Conf({ projectName: 'create-llama' })
if (program.resetPreferences) { if (program.resetPreferences) {
conf.clear() conf.clear()
...@@ -254,42 +219,6 @@ async function run(): Promise<void> { ...@@ -254,42 +219,6 @@ async function run(): Promise<void> {
const getPrefOrDefault = (field: string) => const getPrefOrDefault = (field: string) =>
preferences[field] ?? defaults[field] preferences[field] ?? defaults[field]
if (!program.typescript && !program.javascript) {
if (ciInfo.isCI) {
// default to TypeScript in CI as we can't prompt to
// prevent breaking setup flows
program.typescript = getPrefOrDefault('typescript')
} else {
const styledTypeScript = blue('TypeScript')
const { typescript } = await prompts(
{
type: 'toggle',
name: 'typescript',
message: `Would you like to use ${styledTypeScript}?`,
initial: getPrefOrDefault('typescript'),
active: 'Yes',
inactive: 'No',
},
{
/**
* User inputs Ctrl+C or Ctrl+D to exit the prompt. We should close the
* process and not write to the file system.
*/
onCancel: () => {
console.error('Exiting.')
process.exit(1)
},
}
)
/**
* Depending on the prompt response, set the appropriate program flags.
*/
program.typescript = Boolean(typescript)
program.javascript = !Boolean(typescript)
preferences.typescript = Boolean(typescript)
}
}
if ( if (
!process.argv.includes('--eslint') && !process.argv.includes('--eslint') &&
!process.argv.includes('--no-eslint') !process.argv.includes('--no-eslint')
...@@ -312,68 +241,6 @@ async function run(): Promise<void> { ...@@ -312,68 +241,6 @@ async function run(): Promise<void> {
} }
} }
if (
!process.argv.includes('--tailwind') &&
!process.argv.includes('--no-tailwind')
) {
if (ciInfo.isCI) {
program.tailwind = getPrefOrDefault('tailwind')
} else {
const tw = blue('Tailwind CSS')
const { tailwind } = await prompts({
onState: onPromptState,
type: 'toggle',
name: 'tailwind',
message: `Would you like to use ${tw}?`,
initial: getPrefOrDefault('tailwind'),
active: 'Yes',
inactive: 'No',
})
program.tailwind = Boolean(tailwind)
preferences.tailwind = Boolean(tailwind)
}
}
if (
!process.argv.includes('--src-dir') &&
!process.argv.includes('--no-src-dir')
) {
if (ciInfo.isCI) {
program.srcDir = getPrefOrDefault('srcDir')
} else {
const styledSrcDir = blue('`src/` directory')
const { srcDir } = await prompts({
onState: onPromptState,
type: 'toggle',
name: 'srcDir',
message: `Would you like to use ${styledSrcDir}?`,
initial: getPrefOrDefault('srcDir'),
active: 'Yes',
inactive: 'No',
})
program.srcDir = Boolean(srcDir)
preferences.srcDir = Boolean(srcDir)
}
}
if (!process.argv.includes('--app') && !process.argv.includes('--no-app')) {
if (ciInfo.isCI) {
program.app = getPrefOrDefault('app')
} else {
const styledAppDir = blue('App Router')
const { appRouter } = await prompts({
onState: onPromptState,
type: 'toggle',
name: 'appRouter',
message: `Would you like to use ${styledAppDir}? (recommended)`,
initial: getPrefOrDefault('app'),
active: 'Yes',
inactive: 'No',
})
program.app = Boolean(appRouter)
}
}
if ( if (
typeof program.importAlias !== 'string' || typeof program.importAlias !== 'string' ||
!program.importAlias.length !program.importAlias.length
...@@ -422,10 +289,8 @@ async function run(): Promise<void> { ...@@ -422,10 +289,8 @@ async function run(): Promise<void> {
packageManager, packageManager,
example: example && example !== 'default' ? example : undefined, example: example && example !== 'default' ? example : undefined,
examplePath: program.examplePath, examplePath: program.examplePath,
typescript: program.typescript,
tailwind: program.tailwind, tailwind: program.tailwind,
eslint: program.eslint, eslint: program.eslint,
appRouter: program.app,
srcDir: program.srcDir, srcDir: program.srcDir,
importAlias: program.importAlias, importAlias: program.importAlias,
}) })
...@@ -450,10 +315,8 @@ async function run(): Promise<void> { ...@@ -450,10 +315,8 @@ async function run(): Promise<void> {
await createApp({ await createApp({
appPath: resolvedProjectPath, appPath: resolvedProjectPath,
packageManager, packageManager,
typescript: program.typescript,
eslint: program.eslint, eslint: program.eslint,
tailwind: program.tailwind, tailwind: program.tailwind,
appRouter: program.app,
srcDir: program.srcDir, srcDir: program.srcDir,
importAlias: program.importAlias, importAlias: program.importAlias,
}) })
...@@ -469,15 +332,15 @@ async function notifyUpdate(): Promise<void> { ...@@ -469,15 +332,15 @@ async function notifyUpdate(): Promise<void> {
if (res?.latest) { if (res?.latest) {
const updateMessage = const updateMessage =
packageManager === 'yarn' packageManager === 'yarn'
? 'yarn global add create-next-app' ? 'yarn global add create-llama'
: packageManager === 'pnpm' : packageManager === 'pnpm'
? 'pnpm add -g create-next-app' ? 'pnpm add -g create-llama'
: packageManager === 'bun' : packageManager === 'bun'
? 'bun add -g create-next-app' ? 'bun add -g create-llama'
: 'npm i -g create-next-app' : 'npm i -g create-llama'
console.log( console.log(
yellow(bold('A new version of `create-next-app` is available!')) + yellow(bold('A new version of `create-llama` is available!')) +
'\n' + '\n' +
'You can update by running: ' + 'You can update by running: ' +
cyan(updateMessage) + cyan(updateMessage) +
......
{ {
"name": "create-next-app", "name": "create-llama",
"version": "13.5.6", "version": "0.0.1",
"keywords": [ "keywords": [
"react", "rag",
"next", "llamaindex",
"next.js" "next.js"
], ],
"description": "Create Next.js-powered React apps with one command", "description": "Create LlamaIndex-powered apps with one command",
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://github.com/vercel/next.js", "url": "https://github.com/run-llama/LlamaIndexTS",
"directory": "packages/create-next-app" "directory": "packages/create-llama"
}, },
"author": "Next.js Team <support@vercel.com>", "author": "LlamaIndex Team <info@runllama.ai>",
"license": "MIT", "license": "MIT",
"bin": { "bin": {
"create-next-app": "./dist/index.js" "create-llama": "./dist/index.js"
}, },
"files": [ "files": [
"dist" "dist"
......
import { install } from '../helpers/install'
import { makeDir } from '../helpers/make-dir'
import { copy } from '../helpers/copy'
import { async as glob } from 'fast-glob'
import os from 'os'
import fs from 'fs/promises'
import path from 'path'
import { cyan, bold } from 'picocolors'
import { Sema } from 'async-sema'
import { version } from '../package.json'
import { GetTemplateFileArgs, InstallTemplateArgs } from './types'
/**
* Get the file path for a given file in a template, e.g. "next.config.js".
*/
export const getTemplateFile = ({
template,
mode,
file,
}: GetTemplateFileArgs): string => {
return path.join(__dirname, template, mode, file)
}
export const SRC_DIR_NAMES = ['app', 'pages', 'styles']
/**
* Install a LlamaIndex internal template to a given `root` directory.
*/
export const installTemplate = async ({
appName,
root,
packageManager,
isOnline,
template,
mode,
tailwind,
eslint,
srcDir,
importAlias,
}: InstallTemplateArgs) => {
console.log(bold(`Using ${packageManager}.`))
/**
* Copy the template files to the target directory.
*/
console.log('\nInitializing project with template:', template, '\n')
const templatePath = path.join(__dirname, template, mode)
const copySource = ['**']
if (!eslint) copySource.push('!eslintrc.json')
if (!tailwind)
copySource.push(
mode == 'nextjs' ? 'tailwind.config.ts' : '!tailwind.config.js',
'!postcss.config.js'
)
await copy(copySource, root, {
parents: true,
cwd: templatePath,
rename(name) {
switch (name) {
case 'gitignore':
case 'eslintrc.json': {
return `.${name}`
}
// README.md is ignored by webpack-asset-relocator-loader used by ncc:
// https://github.com/vercel/webpack-asset-relocator-loader/blob/e9308683d47ff507253e37c9bcbb99474603192b/src/asset-relocator.js#L227
case 'README-template.md': {
return 'README.md'
}
default: {
return name
}
}
},
})
const tsconfigFile = path.join(
root,
'tsconfig.json'
)
await fs.writeFile(
tsconfigFile,
(await fs.readFile(tsconfigFile, 'utf8'))
.replace(
`"@/*": ["./*"]`,
srcDir ? `"@/*": ["./src/*"]` : `"@/*": ["./*"]`
)
.replace(`"@/*":`, `"${importAlias}":`)
)
// update import alias in any files if not using the default
if (importAlias !== '@/*') {
const files = await glob('**/*', {
cwd: root,
dot: true,
stats: false,
})
const writeSema = new Sema(8, { capacity: files.length })
await Promise.all(
files.map(async (file) => {
// We don't want to modify compiler options in [ts/js]config.json
if (file === 'tsconfig.json' || file === 'jsconfig.json') return
await writeSema.acquire()
const filePath = path.join(root, file)
if ((await fs.stat(filePath)).isFile()) {
await fs.writeFile(
filePath,
(
await fs.readFile(filePath, 'utf8')
).replace(`@/`, `${importAlias.replace(/\*/g, '')}`)
)
}
await writeSema.release()
})
)
}
if (srcDir) {
await makeDir(path.join(root, 'src'))
await Promise.all(
SRC_DIR_NAMES.map(async (file) => {
await fs
.rename(path.join(root, file), path.join(root, 'src', file))
.catch((err) => {
if (err.code !== 'ENOENT') {
throw err
}
})
})
)
const isAppTemplate = template.startsWith('app')
// Change the `Get started by editing pages/index` / `app/page` to include `src`
const indexPageFile = path.join(
'src',
isAppTemplate ? 'app' : 'pages',
`${isAppTemplate ? 'page' : 'index'}.tsx`
)
await fs.writeFile(
indexPageFile,
(
await fs.readFile(indexPageFile, 'utf8')
).replace(
isAppTemplate ? 'app/page' : 'pages/index',
isAppTemplate ? 'src/app/page' : 'src/pages/index'
)
)
if (tailwind) {
const tailwindConfigFile = path.join(
root,
'tailwind.config.ts'
)
await fs.writeFile(
tailwindConfigFile,
(
await fs.readFile(tailwindConfigFile, 'utf8')
).replace(
/\.\/(\w+)\/\*\*\/\*\.\{js,ts,jsx,tsx,mdx\}/g,
'./src/$1/**/*.{js,ts,jsx,tsx,mdx}'
)
)
}
}
/** Create a package.json for the new project and write it to disk. */
const packageJson: any = {
name: appName,
version: '0.1.0',
private: true,
scripts: {
dev: 'next dev',
build: 'next build',
start: 'next start',
lint: 'next lint',
},
/**
* Default dependencies.
*/
dependencies: {
react: '^18',
'react-dom': '^18',
next: process.env.NEXT_PRIVATE_TEST_VERSION ?? version,
},
devDependencies: {},
}
/**
* TypeScript projects will have type definitions and other devDependencies.
*/
packageJson.devDependencies = {
...packageJson.devDependencies,
typescript: '^5',
'@types/node': '^20',
'@types/react': '^18',
'@types/react-dom': '^18',
}
/* Add Tailwind CSS dependencies. */
if (tailwind) {
packageJson.devDependencies = {
...packageJson.devDependencies,
autoprefixer: '^10',
postcss: '^8',
tailwindcss: '^3',
}
}
/* Default ESLint dependencies. */
if (eslint) {
packageJson.devDependencies = {
...packageJson.devDependencies,
eslint: '^8',
'eslint-config-next': version,
}
}
const devDeps = Object.keys(packageJson.devDependencies).length
if (!devDeps) delete packageJson.devDependencies
await fs.writeFile(
path.join(root, 'package.json'),
JSON.stringify(packageJson, null, 2) + os.EOL
)
console.log('\nInstalling dependencies:')
for (const dependency in packageJson.dependencies)
console.log(`- ${cyan(dependency)}`)
if (devDeps) {
console.log('\nInstalling devDependencies:')
for (const dependency in packageJson.devDependencies)
console.log(`- ${cyan(dependency)}`)
}
console.log()
await install(packageManager, isOnline)
}
export * from './types'
# Rename this file to `.env.local` to use environment variables locally with `next dev`
# https://nextjs.org/docs/pages/building-your-application/configuring/environment-variables
MY_HOST="example.com"
This is a [Next.js](https://nextjs.org/) project bootstrapped with [`create-next-app`](https://github.com/vercel/next.js/tree/canary/packages/create-next-app).
## Getting Started
First, run the development server:
```bash
npm run dev
# or
yarn dev
# or
pnpm dev
# or
bun dev
```
Open [http://localhost:3000](http://localhost:3000) with your browser to see the result.
You can start editing the page by modifying `app/page.tsx`. The page auto-updates as you edit the file.
This project uses [`next/font`](https://nextjs.org/docs/basic-features/font-optimization) to automatically optimize and load Inter, a custom Google Font.
## Learn More
To learn more about Next.js, take a look at the following resources:
- [Next.js Documentation](https://nextjs.org/docs) - learn about Next.js features and API.
- [Learn Next.js](https://nextjs.org/learn) - an interactive Next.js tutorial.
You can check out [the Next.js GitHub repository](https://github.com/vercel/next.js/) - your feedback and contributions are welcome!
## Deploy on Vercel
The easiest way to deploy your Next.js app is to use the [Vercel Platform](https://vercel.com/new?utm_medium=default-template&filter=next.js&utm_source=create-next-app&utm_campaign=create-next-app-readme) from the creators of Next.js.
Check out our [Next.js deployment documentation](https://nextjs.org/docs/deployment) for more details.
import { ChatMessage, OpenAI, SimpleChatEngine } from "llamaindex";
import { NextRequest, NextResponse } from "next/server";
export const runtime = "nodejs";
export const dynamic = "force-dynamic";
export async function POST(request: NextRequest) {
try {
const body = await request.json();
const {
message,
chatHistory,
}: {
message: string;
chatHistory: ChatMessage[];
} = body;
if (!message || !chatHistory) {
return NextResponse.json(
{
error: "message, chatHistory are required in the request body",
},
{ status: 400 }
);
}
const llm = new OpenAI({
model: "gpt-3.5-turbo",
});
const chatEngine = new SimpleChatEngine({
llm,
});
const response = await chatEngine.chat(message, chatHistory);
const result: ChatMessage = {
role: "assistant",
content: response.response,
};
return NextResponse.json({ result });
} catch (error) {
console.error("[LlamaIndex]", error);
return NextResponse.json(
{
error: (error as Error).message,
},
{
status: 500,
}
);
}
}
templates/simple/nextjs/app/favicon.ico

25.3 KiB

@tailwind base;
@tailwind components;
@tailwind utilities;
:root {
--foreground-rgb: 0, 0, 0;
--background-start-rgb: 214, 219, 220;
--background-end-rgb: 255, 255, 255;
}
@media (prefers-color-scheme: dark) {
:root {
--foreground-rgb: 255, 255, 255;
--background-start-rgb: 0, 0, 0;
--background-end-rgb: 0, 0, 0;
}
}
body {
color: rgb(var(--foreground-rgb));
background: linear-gradient(
to bottom,
transparent,
rgb(var(--background-end-rgb))
)
rgb(var(--background-start-rgb));
}
import type { Metadata } from "next";
import { Inter } from "next/font/google";
import "./globals.css";
const inter = Inter({ subsets: ["latin"] });
export const metadata: Metadata = {
title: "Create Llama App",
description: "Generated by create-llama",
};
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body className={inter.className}>{children}</body>
</html>
);
}
import Image from 'next/image'
export default function Home() {
return (
<main className="flex min-h-screen flex-col items-center justify-between p-24">
<div className="z-10 max-w-5xl w-full items-center justify-between font-mono text-sm lg:flex">
<p className="fixed left-0 top-0 flex w-full justify-center border-b border-gray-300 bg-gradient-to-b from-zinc-200 pb-6 pt-8 backdrop-blur-2xl dark:border-neutral-800 dark:bg-zinc-800/30 dark:from-inherit lg:static lg:w-auto lg:rounded-xl lg:border lg:bg-gray-200 lg:p-4 lg:dark:bg-zinc-800/30">
Get started by editing&nbsp;
<code className="font-mono font-bold">app/page.tsx</code>
</p>
<div className="fixed bottom-0 left-0 flex h-48 w-full items-end justify-center bg-gradient-to-t from-white via-white dark:from-black dark:via-black lg:static lg:h-auto lg:w-auto lg:bg-none">
<a
className="pointer-events-none flex place-items-center gap-2 p-8 lg:pointer-events-auto lg:p-0"
href="https://vercel.com?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
target="_blank"
rel="noopener noreferrer"
>
By{' '}
<Image
src="/vercel.svg"
alt="Vercel Logo"
className="dark:invert"
width={100}
height={24}
priority
/>
</a>
</div>
</div>
<div className="relative flex place-items-center before:absolute before:h-[300px] before:w-[480px] before:-translate-x-1/2 before:rounded-full before:bg-gradient-radial before:from-white before:to-transparent before:blur-2xl before:content-[''] after:absolute after:-z-20 after:h-[180px] after:w-[240px] after:translate-x-1/3 after:bg-gradient-conic after:from-sky-200 after:via-blue-200 after:blur-2xl after:content-[''] before:dark:bg-gradient-to-br before:dark:from-transparent before:dark:to-blue-700 before:dark:opacity-10 after:dark:from-sky-900 after:dark:via-[#0141ff] after:dark:opacity-40 before:lg:h-[360px] z-[-1]">
<Image
className="relative dark:drop-shadow-[0_0_0.3rem_#ffffff70] dark:invert"
src="/next.svg"
alt="Next.js Logo"
width={180}
height={37}
priority
/>
</div>
<div className="mb-32 grid text-center lg:max-w-5xl lg:w-full lg:mb-0 lg:grid-cols-4 lg:text-left">
<a
href="https://nextjs.org/docs?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="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"
target="_blank"
rel="noopener noreferrer"
>
<h2 className={`mb-3 text-2xl font-semibold`}>
Docs{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Find in-depth information about Next.js features and API.
</p>
</a>
<a
href="https://nextjs.org/learn?utm_source=create-next-app&utm_medium=appdir-template-tw&utm_campaign=create-next-app"
className="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"
target="_blank"
rel="noopener noreferrer"
>
<h2 className={`mb-3 text-2xl font-semibold`}>
Learn{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Learn about Next.js in an interactive course with&nbsp;quizzes!
</p>
</a>
<a
href="https://vercel.com/templates?framework=next.js&utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="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"
target="_blank"
rel="noopener noreferrer"
>
<h2 className={`mb-3 text-2xl font-semibold`}>
Templates{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Explore the Next.js 13 playground.
</p>
</a>
<a
href="https://vercel.com/new?utm_source=create-next-app&utm_medium=appdir-template&utm_campaign=create-next-app"
className="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"
target="_blank"
rel="noopener noreferrer"
>
<h2 className={`mb-3 text-2xl font-semibold`}>
Deploy{' '}
<span className="inline-block transition-transform group-hover:translate-x-1 motion-reduce:transform-none">
-&gt;
</span>
</h2>
<p className={`m-0 max-w-[30ch] text-sm opacity-50`}>
Instantly deploy your Next.js site to a shareable URL with Vercel.
</p>
</a>
</div>
</main>
)
}
{
"extends": "next/core-web-vitals"
}
# 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
# vercel
.vercel
# typescript
*.tsbuildinfo
next-env.d.ts
/// <reference types="next" />
/// <reference types="next/image-types/global" />
// NOTE: This file should not be edited
// see https://nextjs.org/docs/basic-features/typescript for more information.
/** @type {import('next').NextConfig} */
const nextConfig = {}
module.exports = nextConfig
module.exports = {
plugins: {
tailwindcss: {},
autoprefixer: {},
},
}
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 394 80"><path fill="#000" d="M262 0h68.5v12.7h-27.2v66.6h-13.6V12.7H262V0ZM149 0v12.7H94v20.4h44.3v12.6H94v21h55v12.6H80.5V0h68.7zm34.3 0h-17.8l63.8 79.4h17.9l-32-39.7 32-39.6h-17.9l-23 28.6-23-28.6zm18.3 56.7-9-11-27.1 33.7h17.8l18.3-22.7z"/><path fill="#000" d="M81 79.3 17 0H0v79.3h13.6V17l50.2 62.3H81Zm252.6-.4c-1 0-1.8-.4-2.5-1s-1.1-1.6-1.1-2.6.3-1.8 1-2.5 1.6-1 2.6-1 1.8.3 2.5 1a3.4 3.4 0 0 1 .6 4.3 3.7 3.7 0 0 1-3 1.8zm23.2-33.5h6v23.3c0 2.1-.4 4-1.3 5.5a9.1 9.1 0 0 1-3.8 3.5c-1.6.8-3.5 1.3-5.7 1.3-2 0-3.7-.4-5.3-1s-2.8-1.8-3.7-3.2c-.9-1.3-1.4-3-1.4-5h6c.1.8.3 1.6.7 2.2s1 1.2 1.6 1.5c.7.4 1.5.5 2.4.5 1 0 1.8-.2 2.4-.6a4 4 0 0 0 1.6-1.8c.3-.8.5-1.8.5-3V45.5zm30.9 9.1a4.4 4.4 0 0 0-2-3.3 7.5 7.5 0 0 0-4.3-1.1c-1.3 0-2.4.2-3.3.5-.9.4-1.6 1-2 1.6a3.5 3.5 0 0 0-.3 4c.3.5.7.9 1.3 1.2l1.8 1 2 .5 3.2.8c1.3.3 2.5.7 3.7 1.2a13 13 0 0 1 3.2 1.8 8.1 8.1 0 0 1 3 6.5c0 2-.5 3.7-1.5 5.1a10 10 0 0 1-4.4 3.5c-1.8.8-4.1 1.2-6.8 1.2-2.6 0-4.9-.4-6.8-1.2-2-.8-3.4-2-4.5-3.5a10 10 0 0 1-1.7-5.6h6a5 5 0 0 0 3.5 4.6c1 .4 2.2.6 3.4.6 1.3 0 2.5-.2 3.5-.6 1-.4 1.8-1 2.4-1.7a4 4 0 0 0 .8-2.4c0-.9-.2-1.6-.7-2.2a11 11 0 0 0-2.1-1.4l-3.2-1-3.8-1c-2.8-.7-5-1.7-6.6-3.2a7.2 7.2 0 0 1-2.4-5.7 8 8 0 0 1 1.7-5 10 10 0 0 1 4.3-3.5c2-.8 4-1.2 6.4-1.2 2.3 0 4.4.4 6.2 1.2 1.8.8 3.2 2 4.3 3.4 1 1.4 1.5 3 1.5 5h-5.8z"/></svg>
\ No newline at end of file
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 283 64"><path fill="black" d="M141 16c-11 0-19 7-19 18s9 18 20 18c7 0 13-3 16-7l-7-5c-2 3-6 4-9 4-5 0-9-3-10-7h28v-3c0-11-8-18-19-18zm-9 15c1-4 4-7 9-7s8 3 9 7h-18zm117-15c-11 0-19 7-19 18s9 18 20 18c6 0 12-3 16-7l-8-5c-2 3-5 4-8 4-5 0-9-3-11-7h28l1-3c0-11-8-18-19-18zm-10 15c2-4 5-7 10-7s8 3 9 7h-19zm-39 3c0 6 4 10 10 10 4 0 7-2 9-5l8 5c-3 5-9 8-17 8-11 0-19-7-19-18s8-18 19-18c8 0 14 3 17 8l-8 5c-2-3-5-5-9-5-6 0-10 4-10 10zm83-29v46h-9V5h9zM37 0l37 64H0L37 0zm92 5-27 48L74 5h10l18 30 17-30h10zm59 12v10l-3-1c-6 0-10 4-10 10v15h-9V17h9v9c0-5 6-9 13-9z"/></svg>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment