Skip to content
Back

How to Display File in Web?

  • 0
  • 3
  • Web
  • Cloud
Dan6erbond
12 Mar, 2026, 16:40

I'm trying to use Appwrite's Storage to store images and display them in my app, however when I use the getFileView, getFileDownload or getFilePreview methods the client throws a ERR_BLOCKED_BY_ORB.

I can access the file as an admin here: https://fra.cloud.appwrite.io/v1/storage/buckets/69b2d73500215daa4d65/files/69b2e559002dfb8caa8b/view?project=skincare-buddy&mode=admin

But if I remove the mode=admin it doesn't work. How do I make files publicly accessible? Or at least accessible to the logged-in user?

I'm using Next.js, so the session is stored as a cookie and then populated back into the Appwrite client with client.setSession() so I'm not sure if that migh tbe related.

TL;DR
To display a file in a web application using Appwrite, you need to generate a token for the file and create a link with that token for sharing. The issue arises when users who create files can't access them due to authentication problems when the session is stored on the server. One solution is to generate a token on-the-fly with a workaround route. Another suggested approach is to handle authentication on the client-side following Appwrite's recommended method of setting cookies for access. The user shared a GitHub issue and their own solution involving a client.call method for authentication.
Dan6erbond
12 Mar, 2026, 16:57

I've been sort of able to solve it by giving the file the Permission.read(Role.any()) but that's not really ideal and it would be better if there's a way to manually pass the session to the URL.

12 Mar, 2026, 17:36

You need to generate a Token for that file and then generate a link for that file with that token if you want to share that file with others. Tokens have life-time property which you can utilise.

12 Mar, 2026, 17:38

Refer to this

12 Mar, 2026, 17:39

I get that, however the thing is I'd like the user who creates the file to have access to it only, really, but because I'm using client.setSession it looks like the file API basically considers the request unauthorized. Is there no way to pass the session to the API via query params?

12 Mar, 2026, 17:40

Do you have row level permissions on ?

12 Mar, 2026, 17:41

And Tokens seem to only be available from node-appwrite so I can only generate those on the server, which I just did as a workaround. I have a Next.js API route that redirects to Appwrite's file URL after generating a token if none exist. But that seems extremely hacky.

12 Mar, 2026, 17:41

Yep. The user has read access, as I mentioned that works fine. The issue is more so that the view URL is useless because the user isn't authorized via cookies.

12 Mar, 2026, 17:42

Or at least not an Appwrite cookie lol.

12 Mar, 2026, 17:43

So the user who uploads let's say a picture is not able to see the picture if he tries to open it by clicking the link generated via the FileView or something property?

12 Mar, 2026, 17:45

Yes because when the user logs in I run createSession on the server, store it in a cookie on my site, then populate the client with the session using setSession. So Appwrite doesn't really "know" the user when a direct request is made to the API without headers which is what happens when I try to load images.

12 Mar, 2026, 17:45

The user can read/update the file just fine, not view it because of the auth.

12 Mar, 2026, 17:46

That should not happen even if it's client sided

12 Mar, 2026, 17:46

Appwrite has no way of knowing the user. How could it if I am logging them in server-side?

12 Mar, 2026, 17:48

Oh yeah

12 Mar, 2026, 17:48

My bad

12 Mar, 2026, 17:49

That did happen to me when I was building a g-drive clone I was not able to view the file unless I viewed it in admin mode or downloaded it just to see it

12 Mar, 2026, 17:50

The only solution was the token

13 Mar, 2026, 08:47

I had a similar problem. There’s also an issue on GitHub repo. Take a look at my comment here https://github.com/appwrite/appwrite/issues/11335#issuecomment-3924064947

13 Mar, 2026, 08:49

I had to use appwrite client.call() method to get it to work. Hacky but it works

13 Mar, 2026, 09:00

I might have explained my issue poorly, I think it's different to yours <@243124669685694474> because you said your error is a 404 for the bucket, and that you have permissions for the role "any" with full CRUD enabled, and no File Security. In my case I only have create enabled for users, and File Security so when a file is created I do this:

TypeScript
const fileUpload = await storage.createFile({
  bucketId,
  fileId: ID.unique(),
  file: image,
  permissions: [
    Permission.read(Role.user(user.$id)),
    Permission.update(Role.user(user.$id)),
    Permission.delete(Role.user(user.$id)),
  ],
});```
But my user logs into my app server-side and I store the session in my own cookie, not Appwrite's:
```ts
export async function signInWithEmail(formData: FormData) {
  const email = formData.get("email")! as string;
  const password = formData.get("password")! as string;

  const { account } = await createAdminClient();

  const session = await account.createEmailPasswordSession({
    email,
    password,
  });

  (await cookies()).set(APPWRITE_SESSION_KEY, session.secret, {
    path: "/",
    httpOnly: true,
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
  });

  redirect("/dashboard");
}```
Which means that there aren't any Appwrite cookies for the user to be authenticated when I pass an image URL to the `<img>` tag.
13 Mar, 2026, 09:00

Hence why I had to create this trick-route that generates a File Token on-the-fly:

TypeScript
export async function GET(
  _: NextRequest,
  ctx: RouteContext<"/api/files/[id]">,
) {
  const { id } = await ctx.params;

  const { storage } = await createSessionClient();

  const file = await storage.getFile({
    bucketId,
    fileId: id,
  });

  const { tokens } = await createAdminClient();

  let token: string | undefined;

  const { tokens: tokensList } = await tokens.list({
    bucketId: file.bucketId,
    fileId: file.$id,
    total: false,
  });

  if (tokensList.length > 0) {
    token = tokensList[0].secret;
  } else {
    token = await tokens
      .createFileToken({
        bucketId: file.bucketId,
        fileId: file.$id,
      })
      .then((tok) => tok.secret);
  }

  const { storage: storageClient } = createClient();

  return NextResponse.redirect(
    storageClient.getFileView({
      bucketId: file.bucketId,
      fileId: file.$id,
      token,
    }),
  );
}```
13 Mar, 2026, 09:00

Appwrite should ideally have a way users can access files by appending ?session to the /view URL.

13 Mar, 2026, 18:44

Okay I think I know what's going on. And I think that I had not quite identical, but similar issue.

TypeScript
export async function signInWithEmail(formData: FormData) {
  const email = formData.get("email")! as string;
  const password = formData.get("password")! as string;

  const { account } = await createAdminClient();

  const session = await account.createEmailPasswordSession({
    email,
    password,
  });
// up to this point everything is quite right
// but there:
// you set the cookie that will never be sent to appwrite, because of how cookies work
// so the APPWRITE_SESSION_KEY will never be send anywhere
  (await cookies()).set(APPWRITE_SESSION_KEY, session.secret, {  
    path: "/",
    httpOnly: true,
    sameSite: "lax",
    secure: process.env.NODE_ENV === "production",
  });

  redirect("/dashboard");
}

what you can do is to call:

TypeScript
client.call()

with your url, and manually pass X-Fallback-Cookies header, or genereate JWT and pass X-Appwrite-JWT.

Reply

Reply to this thread by joining our Discord

Reply on Discord

Need support?

Join our Discord

Get community support by joining our Discord server.

Join Discord

Get premium support

Join Appwrite Pro and get email support from our team.

Learn more