Skip to main content
Docs

Use image optimization to improve app performance

When displaying your users' profile images, you should use query parameters to specify a maximum size and minimum quality. Doing so can allow you to improve your app's overall page load times by reducing the file sizes of the images you're fetching.

Add query parameters to imageUrl

Some types in Clerk's JavaScript SDK, such as User, PublicUserData, and Organization, have an imageUrl. The URL returned from this property can be scaled down with the following image optimization options:

  • "width": Sets the minimum width of the image in pixels.
  • "height": Sets the minimum height of the image in pixels.
  • "fit": Describes how the image should fit its container. It can take the following values:
    • "scale-down": The image will scale down to fit the sizes specified in "width" and "height" if it's bigger, but will not scale up if it's smaller.
    • "crop": The image will scale down and be cropped to fit within the area specified in "width" and "height".
  • "quality": Specifies the image quality for JPEG, WebP, PNG, and AVIF files. Accepts values from 1 to 100. Defaults to 85.

Example

The following example demonstrates how you can get the imageUrl from the currently active user in a session, and display their profile picture using Clerk's image optimization options.

On the client-side, you can use the useClerk() hook to get the imageUrl from the currently active user's User object.

export default function ImageOptimization() {
  // Use the `useClerk()` hook to get the current user's `User` object
  const clerk = useClerk()
  const { user } = clerk
  if (!user) return <p>No Image URL found</p>

  // Get the image URL from the user's `User` object
  const { imageUrl } = user

  // Add image optimization options to the image URL
  const params = new URLSearchParams()
  params.set('height', '200')
  params.set('width', '200')
  params.set('quality', '100')
  params.set('fit', 'crop')

  // Construct the final image URL with the optimization options
  const imageSrc = `${imageUrl}?${params.toString()}`

  return (
    <div>
      <h1>Image source:</h1>
      <p>{imageSrc}</p>
      <h2>Image:</h2>
      <img src={imageSrc} alt="User image" />
    </div>
  )
}

On the server-side, you can use the getUser() method to get the imageUrl from the user's User object, and display their profile picture using Clerk's image optimization options.

getUser() requires a valid user ID. You can access the current user's ID from the Auth object.

app/image-optimization/page.tsx
export default async function ImageOptimization() {
  // Get the user's ID from the `Auth` object
  // Accessing the `Auth` object differs depending on the SDK you're using
  // https://clerk.com/docs/reference/backend/types/auth-object#how-to-access-the-auth-object
  const { userId } = await auth()

  // Initialize `clerkClient()`
  // This varies depending on the SDK you're using
  // https://clerk.com/docs/js-backend/getting-started/quickstart
  const client = await clerkClient()

  // Use the `getUser()` method to get the `User` object
  const user = await client.users.getUser(userId)

  if (!user) return <p>No Image URL found</p>

  // Get the image URL from the user's `User` object
  const { imageUrl } = user

  // Add image optimization options to the image URL
  const params = new URLSearchParams()
  params.set('height', '200')
  params.set('width', '200')
  params.set('quality', '100')
  params.set('fit', 'crop')

  // Construct the final image URL with the optimization options
  const imageSrc = `${imageUrl}?${params.toString()}`

  return (
    <div>
      <h1>Image source:</h1>
      <p>{imageSrc}</p>
      <h2>Image:</h2>
      <img src={imageSrc} alt="User image" />
    </div>
  )
}

The Next.js SDK offers the currentUser()Next.js Icon helper to get the current user's User object. This is more efficient than using the getUser() method directly as it abstracts the user ID retrieval and user object fetching into a single helper.

app/image-optimization/page.tsx
import { currentUser } from '@clerk/nextjs/server'

export default async function ImageOptimization() {
  // Use the `currentUser()` helper to get the current user's `User` object
  const user = await currentUser()
  if (!user) return <p>No Image URL found</p>

  // Get the image URL from the user's `User` object
  const { imageUrl } = user

  // Add image optimization options to the image URL
  const params = new URLSearchParams()
  params.set('height', '200')
  params.set('width', '200')
  params.set('quality', '100')
  params.set('fit', 'crop')

  // Construct the final image URL with the optimization options
  const imageSrc = `${imageUrl}?${params.toString()}`

  return (
    <div>
      <h1>Image source:</h1>
      <p>{imageSrc}</p>
      <h2>Image:</h2>
      <img src={imageSrc} alt="User image" />
    </div>
  )
}

The Astro SDK offers the locals.currentUser()Astro Icon local to get the current user's User object. This is more efficient than using the getUser() method directly as it abstracts the user ID retrieval and user object fetching into a single local.

src/pages/image-optimization.astro
---
const user = await Astro.locals.currentUser()

if (!user) throw new Error('No Image URL found')

// Get the image URL from the user's `User` object
const { imageUrl } = user

// Add image optimization options to the image URL
const params = new URLSearchParams()
params.set('height', '200')
params.set('width', '200')
params.set('quality', '100')
params.set('fit', 'crop')

// Construct the final image URL with the optimization options
const imageSrc = `${imageUrl}?${params.toString()}`
---

<div>
  <h1>Image source:</h1>
  <p>{imageSrc}</p>
  <h2>Image:</h2>
  <img src={imageSrc} alt="User image" />
</div>

Feedback

What did you think of this content?

Last updated on