Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Images, assets and icons

Assets are files that ship with the app: images, fonts, sounds. For images from the internet Expo offers the expo-image component with caching and a smooth fade-in, and for small symbols, the @expo/vector-icons set of vector icons.

Images from assets

Put a logo.png file into the assets/images folder of the blog project and include it with require:

// app/about.tsx
import { Image, View } from 'react-native';
 
export default function About() {
  return (
    <View style={{ flex: 1, alignItems: 'center', padding: 16 }}>
      <Image
        source={require('@/assets/images/logo.png')}
        style={{ width: 120, height: 120 }}
        resizeMode="contain"
      />
    </View>
  );
}

The "About" screen shows a 120 by 120 logo. resizeMode="contain" fits the whole image while keeping its proportions; cover fills the whole box, cropping the edges.

Screen density

To keep an image sharp on high-density screens, put versions two and three times larger next to it: logo.png, logo@2x.png, logo@3x.png. The code mentions only logo.png, and React Native picks the right file itself.

expo-image

The Image component from the expo-image package caches images on disk and can fade them in. Install it if it is not in package.json:

npx expo install expo-image

Let us add a cover to the post screen:

// app/posts/[id].tsx
import { Image } from 'expo-image';
 
<Image
  source={`https://picsum.photos/seed/${id}/600/300`}
  style={{ width: '100%', height: 180, borderRadius: 8 }}
  contentFit="cover"
  transition={300}
/>

A full-width photo appears above the post text, fading in over 300 milliseconds. Opening the same post again shows the image instantly, from the cache. expo-image uses the contentFit prop instead of resizeMode, and the address can be passed as a string.

Vector icons

The @expo/vector-icons package is already installed in the template. It contains several sets: Ionicons, MaterialIcons, FontAwesome and others.

// app/posts/[id].tsx
import { Ionicons } from '@expo/vector-icons';
import { Text, View } from 'react-native';
 
<View style={{ flexDirection: 'row', alignItems: 'center', gap: 6 }}>
  <Ionicons name="chatbubble-outline" size={18} color="#666" />
  <Text style={{ color: '#666' }}>5 comments</Text>
</View>

A grey speech bubble appears next to the comment count. An icon is a font glyph, so its size and color change with the size and color props without losing sharpness. You can look up icon names in the directory at icons.expo.fyi.

Common mistake

Building the require path from a variable: require('@/assets/images/' + name). Metro finds asset files at build time and cannot run such code, so the app fails to build. Write every path in full, and if you need to choose an image, make an object: const icons = { cat: require('...cat.png'), dog: require('...dog.png') }.

Thanks for reading!

Donate to the site — we work hard for you.