Skip to content

Commit 0ca417b

Browse files
authored
Merge branch 'main' into docs/fix-python-tablesdb
2 parents 51f4294 + f952c79 commit 0ca417b

File tree

20 files changed

+14965
-54
lines changed

20 files changed

+14965
-54
lines changed

pnpm-lock.yaml

Lines changed: 12557 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/lib/constants.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type SocialStats = {
88

99
export const SOCIAL_STATS: SocialStats = {
1010
GITHUB: {
11-
STAT: '52K',
11+
STAT: '53K',
1212
LINK: 'https://github.com/appwrite/appwrite',
1313
EXTRA: {
1414
COMMITS: '27K+',

src/lib/layouts/Sidebar.svelte

Lines changed: 69 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111
export type NavGroup = {
1212
label?: string;
1313
items: Array<NavLink>;
14+
collapsible?: boolean;
15+
initiallyCollapsed?: boolean;
1416
};
1517
1618
export type NavParent = {
@@ -41,6 +43,27 @@
4143
function isNavLink(item: NavLink | NavGroup): item is NavLink {
4244
return 'href' in item;
4345
}
46+
47+
let collapsedGroups = $state<Record<number, boolean>>({});
48+
49+
$effect(() => {
50+
// Initialize collapsed state for collapsible groups
51+
navigation.forEach((navGroup, index) => {
52+
if (!isNavLink(navGroup) && navGroup.collapsible) {
53+
if (!(index in collapsedGroups)) {
54+
collapsedGroups[index] = navGroup.initiallyCollapsed ?? true;
55+
}
56+
}
57+
});
58+
});
59+
60+
function isCollapsed(index: number): boolean {
61+
return collapsedGroups[index] ?? true;
62+
}
63+
64+
function toggleGroup(index: number) {
65+
collapsedGroups[index] = !isCollapsed(index);
66+
}
4467
</script>
4568

4669
<nav
@@ -79,7 +102,7 @@
79102
>
80103
</section>
81104
{/if}
82-
{#each navigation as navGroup}
105+
{#each navigation as navGroup, index}
83106
<section>
84107
{#if isNavLink(navGroup)}
85108
{#if expandable && !$layoutState.showSidenav}
@@ -94,28 +117,53 @@
94117
{/if}
95118
{:else}
96119
{#if navGroup.label}
97-
<h2
98-
class="text-eyebrow web-side-nav-header mb-2 whitespace-nowrap uppercase"
99-
>
100-
{navGroup.label}
101-
</h2>
120+
{#if navGroup.collapsible}
121+
<button
122+
class="web-side-nav-header-collapsible text-eyebrow web-side-nav-header mb-2 flex w-full cursor-pointer items-center pr-3 uppercase"
123+
onclick={(e) => {
124+
e.preventDefault();
125+
e.stopPropagation();
126+
toggleGroup(index);
127+
}}
128+
aria-expanded={!isCollapsed(index)}
129+
type="button"
130+
>
131+
<span>{navGroup.label}</span>
132+
<span
133+
class="icon-cheveron-down ml-auto"
134+
aria-hidden="true"
135+
style:transform={isCollapsed(index)
136+
? 'rotate(0deg)'
137+
: 'rotate(180deg)'}
138+
style:transition="transform 0.2s ease-in-out"
139+
></span>
140+
</button>
141+
{:else}
142+
<h2
143+
class="text-eyebrow web-side-nav-header mb-2 whitespace-nowrap uppercase"
144+
>
145+
{navGroup.label}
146+
</h2>
147+
{/if}
102148
{/if}
103-
<ul>
104-
{#each navGroup.items as groupItem}
105-
<li>
106-
{#if expandable && !$layoutState.showSidenav}
107-
<Tooltip placement="right">
149+
{#if !navGroup.collapsible || !isCollapsed(index)}
150+
<ul>
151+
{#each navGroup.items as groupItem}
152+
<li>
153+
{#if expandable && !$layoutState.showSidenav}
154+
<Tooltip placement="right">
155+
<SidebarNavButton {groupItem} />
156+
{#snippet tooltip()}
157+
<span>{groupItem.label}</span>
158+
{/snippet}
159+
</Tooltip>
160+
{:else}
108161
<SidebarNavButton {groupItem} />
109-
{#snippet tooltip()}
110-
<span>{groupItem.label}</span>
111-
{/snippet}
112-
</Tooltip>
113-
{:else}
114-
<SidebarNavButton {groupItem} />
115-
{/if}
116-
</li>
117-
{/each}
118-
</ul>
162+
{/if}
163+
</li>
164+
{/each}
165+
</ul>
166+
{/if}
119167
{/if}
120168
</section>
121169
{/each}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
---
2+
layout: post
3+
title: Next.js standalone builds now supported on Appwrite Sites
4+
description: Deploy Next.js apps in standalone mode on Appwrite Sites with full Next.js 16 support, smaller builds, faster cold starts, and lighter deployments.
5+
date: 2025-11-12
6+
cover: /images/blog/nextjs-standalone-builds/cover.png
7+
timeToRead: 4
8+
author: ebenezer-don
9+
category: announcement
10+
---
11+
12+
You can now deploy Next.js apps built in [standalone mode](https://nextjs.org/docs/app/api-reference/config/next-config-js/output) on Appwrite Sites, with full support for Next.js 16. In standalone mode, the build process creates a smaller package that includes only the files your app needs to run in production, leaving out development tools and unused parts of the framework.
13+
14+
# Why standalone mode?
15+
16+
In our benchmarks, build size dropped by about six times on average, and cold start times were 2x faster. Deployments are lighter with faster build times, and sites start responding more quickly after going live.
17+
18+
This work began with a report by a community member, [Warfin](https://github.com/WarFiN123), about build issues in Next.js 16. Those discussions led to deeper improvements in how Appwrite handles builds, which made standalone support possible.
19+
20+
# How to enable Next.js standalone mode
21+
22+
To enable standalone mode, open your `next.config.js` file and add `output: 'standalone'` to your existing configuration:
23+
24+
```js
25+
/** @type {import('next').NextConfig} */
26+
module.exports = {
27+
output: 'standalone',
28+
};
29+
```
30+
31+
Then build your project as usual. Appwrite Sites now recognizes that output automatically, so you can deploy it directly with no further changes.
32+
33+
This update also lays the groundwork for broader improvements as we better understand how we can apply the same benefits to all Next.js builds, and eventually to all SSR builds.
34+
35+
We're excited to see what you ship next!
36+

src/routes/cloud-ga/(components)/open-source-community.svelte

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
};
1616
1717
const numbers = [
18-
{ label: '52k+', description: 'GitHub stars' },
18+
{ label: '53k+', description: 'GitHub stars' },
1919
{ label: '250k+', description: 'Followers across socials' },
2020
{ label: '46k+', description: 'Contributions to GitHub' },
2121
{ label: '610k+', description: 'Discord messages' }

src/routes/docs/+page.svelte

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -280,58 +280,58 @@
280280
</li>
281281
<li>
282282
<a
283-
href="/docs/apis/realtime"
283+
href="/docs/products/avatars"
284284
class="web-card is-normal"
285-
onclick={() => trackEvent(`docs-products_realtime-click`)}
285+
onclick={() => trackEvent(`docs-products_avatars-click`)}
286286
>
287287
<img
288-
src="/images/icons/illustrated/dark/realtime.png"
288+
src="/images/icons/illustrated/dark/avatars.png"
289289
alt=""
290290
class="web-u-only-dark"
291291
width="40"
292292
height="40"
293293
/>
294294
<img
295-
src="/images/icons/illustrated/light/realtime.png"
295+
src="/images/icons/illustrated/light/avatars.png"
296296
alt=""
297297
class="web-u-only-light"
298298
width="40"
299299
height="40"
300300
/>
301-
<h4 class="text-sub-body text-primary mt-2 font-medium">Realtime</h4>
302-
<p class="text-sub-body mt-1">Respond to server events in realtime.</p>
301+
<h4 class="text-sub-body text-primary mt-2 font-medium">Avatars</h4>
302+
<p class="text-sub-body mt-1">
303+
Generate icons, screenshots, and QR codes for your apps.
304+
</p>
303305
</a>
304306
</li>
305307
<li>
306308
<a
307-
href="/docs/products/network"
309+
href="/docs/apis/realtime"
308310
class="web-card is-normal"
309-
onclick={() => trackEvent(`docs-products_network-click`)}
311+
onclick={() => trackEvent(`docs-products_realtime-click`)}
310312
>
311313
<img
312-
src="/images/icons/illustrated/dark/network.png"
314+
src="/images/icons/illustrated/dark/realtime.png"
313315
alt=""
314316
class="web-u-only-dark"
315317
width="40"
316318
height="40"
317319
/>
318320
<img
319-
src="/images/icons/illustrated/light/network.png"
321+
src="/images/icons/illustrated/light/realtime.png"
320322
alt=""
321323
class="web-u-only-light"
322324
width="40"
323325
height="40"
324326
/>
325-
<h4 class="text-sub-body text-primary mt-2 font-medium">Network</h4>
326-
<p class="text-sub-body mt-1">
327-
Global infrastructure for serverless compute.
328-
</p>
327+
<h4 class="text-sub-body text-primary mt-2 font-medium">Realtime</h4>
328+
<p class="text-sub-body mt-1">Respond to server events in realtime.</p>
329329
</a>
330330
</li>
331331
</ul>
332332
</div>
333333
</section>
334-
<section class="web-hero is-align-start is-no-max-width border-smooth border-t pt-12!">
334+
<section class="web-hero is-align-start is-no-max-width mt-12!">
335335
<h2 class="text-title font-aeonik-pro text-primary max-w-[600px]">
336336
Build faster with AI
337337
</h2>

src/routes/docs/Sidebar.svelte

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,18 @@
2525
href: '/docs/sdks',
2626
icon: 'icon-cog'
2727
},
28+
{
29+
label: 'Changelog',
30+
href: '/changelog',
31+
icon: 'icon-clock',
32+
openInNewTab: true
33+
},
34+
{
35+
label: 'Integrations',
36+
href: '/integrations',
37+
icon: 'icon-puzzle',
38+
openInNewTab: true
39+
},
2840
{
2941
label: 'API references',
3042
href: '/docs/references',
@@ -72,18 +84,20 @@
7284
icon: 'icon-globe-alt',
7385
isParent: true,
7486
new: isNewUntil('19 Jul 2025')
75-
},
76-
{
77-
label: 'Network',
78-
href: '/docs/products/network',
79-
icon: 'icon-share',
80-
isParent: true
81-
},
87+
}
88+
]
89+
},
90+
{
91+
label: 'Utilities',
92+
collapsible: true,
93+
initiallyCollapsed: true,
94+
items: [
8295
{
83-
label: 'AI',
84-
href: '/docs/products/ai',
85-
icon: 'icon-chip',
86-
isParent: true
96+
label: 'Avatars',
97+
href: '/docs/products/avatars',
98+
icon: 'icon-user-circle',
99+
isParent: true,
100+
new: isNewUntil('1 Jan 2026')
87101
}
88102
]
89103
},
@@ -148,11 +162,10 @@
148162
isParent: true
149163
},
150164
{
151-
label: 'Integrations',
152-
href: '/integrations',
153-
icon: 'icon-puzzle',
154-
isParent: true,
155-
openInNewTab: true
165+
label: 'Network',
166+
href: '/docs/products/network',
167+
icon: 'icon-share',
168+
isParent: true
156169
},
157170
{
158171
label: 'Migrations',
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
<script lang="ts">
2+
import Docs from '$lib/layouts/Docs.svelte';
3+
import Sidebar, { type NavParent, type NavTree } from '$lib/layouts/Sidebar.svelte';
4+
5+
const parent: NavParent = {
6+
href: '/docs',
7+
label: 'Avatars'
8+
};
9+
10+
const navigation: NavTree = [
11+
{
12+
label: 'Getting started',
13+
items: [
14+
{
15+
label: 'Overview',
16+
href: '/docs/products/avatars'
17+
},
18+
{
19+
label: 'Quick start',
20+
href: '/docs/products/avatars/quick-start'
21+
}
22+
]
23+
},
24+
{
25+
label: 'Concepts',
26+
items: [
27+
{
28+
label: 'User initials',
29+
href: '/docs/products/avatars/initials'
30+
},
31+
{
32+
label: 'QR codes',
33+
href: '/docs/products/avatars/qr-codes'
34+
},
35+
{
36+
label: 'Country flags',
37+
href: '/docs/products/avatars/flags'
38+
},
39+
{
40+
label: 'Browser icons',
41+
href: '/docs/products/avatars/browsers'
42+
},
43+
{
44+
label: 'Payment methods',
45+
href: '/docs/products/avatars/payment-methods'
46+
},
47+
{
48+
label: 'Favicons',
49+
href: '/docs/products/avatars/favicons'
50+
},
51+
{
52+
label: 'Image proxy',
53+
href: '/docs/products/avatars/image-manipulation'
54+
}
55+
]
56+
},
57+
{
58+
label: 'References',
59+
items: [
60+
{
61+
label: 'Avatars API',
62+
href: '/docs/references/cloud/client-web/avatars'
63+
}
64+
]
65+
}
66+
];
67+
</script>
68+
69+
<Docs variant="two-side-navs">
70+
<Sidebar {navigation} {parent} />
71+
<slot />
72+
</Docs>

0 commit comments

Comments
 (0)