Skip to content

Commit 2323c29

Browse files
committed
improving next.js quick start
1 parent 17d2579 commit 2323c29

File tree

1 file changed

+42
-135
lines changed

1 file changed

+42
-135
lines changed

sqlite-cloud/quick-start-next.mdx

Lines changed: 42 additions & 135 deletions
Original file line numberDiff line numberDiff line change
@@ -23,155 +23,62 @@ npx create-next-app@latest sqlc-quickstart --js --no-tailwind --eslint --app --s
2323
cd sqlc-quickstart && npm install @sqlitecloud/drivers
2424
```
2525
4. **Instantiate a connection**
26+
- Create a `.env.local` file in the root of your Next.js project and add your SQLiteCloud connection string:
27+
``bash
28+
SQLITECLOUD_URL=your_connection_string_here
29+
```
2630
- The Database driver establishes a TLS connection when used in Node.js, and a websocket connection when used in the browser.
27-
- It is recommended that you use the Database driver in client-side components.
28-
- To share the connection across pages, you can instantiate the connection in a context provider with the ```use client``` directive. Below is a simplified sample implementation.
29-
30-
```tsx
31-
// src/app/context/DatabaseContext.tsx
32-
'use client';
33-
34-
import { Database } from '@sqlitecloud/drivers';
35-
import { createContext, useContext, useEffect, useRef, useState } from 'react';
36-
37-
interface DatabaseContextType {
38-
db: Database | null;
39-
isConnecting: boolean;
40-
error: Error | null;
41-
}
42-
43-
const DatabaseContext = createContext<DatabaseContextType | undefined>(undefined);
44-
45-
interface DatabaseProviderProps {
46-
children: React.ReactNode;
47-
config: { connectionString: string }
48-
}
49-
50-
export function DatabaseProvider({ children, config }: DatabaseProviderProps) {
51-
const [isConnecting, setIsConnecting] = useState(true);
52-
const [error, setError] = useState<Error | null>(null);
53-
const dbRef = useRef<Database | null>(null);
54-
55-
useEffect(() => {
56-
try {
57-
dbRef.current = new Database(config.connectionString);
58-
59-
// Handle connection events
60-
dbRef.current.on('open', () => {
61-
console.log('open')
62-
setIsConnecting(false);
63-
setError(null);
64-
});
65-
66-
dbRef.current.on('error', (err: Error) => {
67-
console.log('error')
68-
setError(err);
69-
setIsConnecting(false);
70-
});
71-
72-
dbRef.current.on('close', () => {
73-
console.log('closing')
74-
setIsConnecting(false);
75-
dbRef.current = null;
76-
});
77-
78-
} catch (err) {
79-
setError(err instanceof Error ? err : new Error('Failed to initialize database'));
80-
setIsConnecting(false);
81-
}
8231
83-
// Cleanup function
84-
return () => {
85-
if (dbRef.current) {
86-
dbRef.current.close();
87-
dbRef.current = null;
88-
}
89-
};
90-
}, [config]);
9132
92-
return (
93-
<DatabaseContext.Provider
94-
value={{
95-
db: dbRef.current,
96-
isConnecting,
97-
error
98-
}}
99-
>
100-
{children}
101-
</DatabaseContext.Provider>
102-
);
103-
}
104-
105-
export function useDatabaseConnection() {
106-
const context = useContext(DatabaseContext);
107-
108-
if (context === undefined) {
109-
throw new Error('useDatabaseConnection must be used within a DatabaseProvider');
110-
}
33+
---
11134
112-
return context;
113-
}
114-
```
115-
5. **Query data**
116-
- Click the ```Connect``` button in your account dashboard and copy the connection string. Replace ```<your-connection-string>``` in ```page.js``` with your connection string.
117-
- Replace the code in ```layout.js``` and ```page.js``` with the following snippets.
35+
### Using SQLiteCloud in Next.js (App Router)
11836
119-
```jsx
120-
// src/app/layout.js
121-
export default function RootLayout({ children }) {
122-
return (
123-
<html lang="en">
124-
<body>
125-
<DatabaseProvider config={{ connectionString: '<your-connection-string>' }}>
126-
{children}
127-
</DatabaseProvider>
128-
</body>
129-
</html>
130-
);
131-
}
132-
```
37+
#### Fetching Data in a Server Component
13338
134-
```jsx
135-
// src/app/page.js
136-
import { useDatabaseConnection } from './context/DatabaseContext';
137-
import { useEffect, useState } from "react";
138-
import { useDatabaseConnection } from "./useDatabaseConnection";
39+
If you want to fetch data directly from the server and render it in a Server Component, you can do:
13940
140-
export default function Home() {
141-
const { db } = useDatabaseConnection();
142-
const [albums, setAlbums] = useState<any[]>([]);
143-
144-
useEffect(() => {
145-
const getAlbums = async () => {
146-
const result = await db.sql`USE DATABASE chinook.sqlite;
41+
**app/albums/page.tsx (Server Component)**
42+
```tsx
43+
import { Database } from "sqlitecloud";
44+
import { unstable_noStore as noStore } from "next/cache";
45+
46+
export default async function AlbumsPage() {
47+
noStore(); // Prevents Next.js from caching the database request
48+
const db = new Database(process.env.SQLITECLOUD_URL!);
49+
50+
try {
51+
const result = await db.sql(`
52+
USE DATABASE chinook.sqlite;
14753
SELECT albums.AlbumId as id, albums.Title as title, artists.name as artist
14854
FROM albums
14955
INNER JOIN artists
15056
WHERE artists.ArtistId = albums.ArtistId
151-
LIMIT 20;`;
152-
return result;
153-
};
154-
155-
if (db) {
156-
getAlbums().then((result) => {
157-
setAlbums(result);
158-
});
159-
}
160-
}, [db]);
161-
162-
return (
163-
<div>
164-
<h1>Albums</h1>
165-
<ul>
166-
{albums.map((album) => (
167-
<div key={album.id}>{album.title}</div>
168-
))}
169-
</ul>
170-
</div>
171-
);
57+
LIMIT 20;
58+
`);
59+
60+
return (
61+
<div>
62+
<h1>Albums</h1>
63+
<ul>
64+
{result.map((album: any) => (
65+
<li key={album.id}>
66+
{album.title} - {album.artist}
67+
</li>
68+
))}
69+
</ul>
70+
</div>
71+
);
72+
} catch (error) {
73+
return <p>Error loading albums: {error.message}</p>;
74+
} finally {
75+
db.close();
76+
}
17277
}
17378
```
17479

80+
81+
17582
5. **Run your app**
17683
```bash
17784
npm run dev

0 commit comments

Comments
 (0)