---
title: Link to other content
slug: cms-11/dev-docs/linking-to-other-content
docTags: 
createdAt: 2026-07-22T19:45:19.953Z
---

The following examples show how to use `ContentReference` to link to different types of content, for example, images and folders.

```csharp
[UIHint(UIHint.Block)]
public virtual ContentReference BlockReference {
  get;
  set;
}

[UIHint(UIHint.BlockFolder)] //BlockFolder and MediaFolder gives the same result since the folder structure is the same
public virtual ContentReference Folder {
  get;
  set;
}

[UIHint(UIHint.Image)] //Anything that implements IContentImage
public virtual ContentReference Image {
  get;
  set;
}

[UIHint(UIHint.Video)] //Anything that implements IContentVideo
public virtual ContentReference Video {
  get;
  set;
}

[UIHint(UIHint.MediaFile)]
public virtual ContentReference MediaFileOfAnyType {
  get;
  set;
}
```

:::hint{type="info"}
**Note**
The code example refers to images and media using a content reference. Optimizely Content Management System (CMS 7) uses a URL in the following code.
:::

```csharp
[UIHint(UIHint.MediaFile)]
public virtual Url FileAsUrl {
  get;
  set;
}

[UIHint(UIHint.Image)]
public virtual Url ImageAsUrl {
  get;
  set;
}
```

CMS supports both types, but you should use `ContentReference`.

If you use a URL, CMS converts the value from its internally permanent URL format to a public and user-friendly format. It is an additional step that has a small impact on performance. For example, when you want to append information to a URL, such as the size or format to use for an image, you must use the URL type because the `ContentReference` stores only the reference and not additional information.

The following image shows how the **Select Block** dialog box displays. The dialog box shows folders and blocks only. Folders are not selectable.

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/Q3MiSJhzhgqYOwXBIzei7-20260722-194633.jpg)

If you skip the UI hint and get a selection for any content on the site, the dialog box displays as follows:

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/SSm6NJY2d4dBb2uBe82_Y-20260722-194633.jpg)

## Customize selection of content

If you want to narrow down the selection, use the `AllowedTypes` attribute to define what you can select:

```csharp
[AllowedTypes(new [] {
  typeof (TeaserBlock)
})]
public virtual ContentReference TeaserBlockReference {
  get;
  set;
}
```

![](https://api.archbee.com/api/optimize/BrbvVORKJ5iIeSMZye5kI/tOLnBpkekmmFj43GtmiNR-20260722-194633.jpg)

You can also further customize the selection by specifying custom roots for the dialog box by creating a custom editor descriptor that inherits from `ContentReferenceEditorDescriptor<T>`. The following example uses a hard-coded content reference for simplicity (but it is not a recommended approach).

```csharp
public class StartPage: SitePageData {
  [UIHint("teaserblock")]
  public virtual ContentReference TeaserBlockReference {
    get;
    set;
  }
}

[EditorDescriptorRegistration(TargetType = typeof (ContentReference), UIHint = "teaserblock")]
public class BlockReferenceEditorDescriptor: ContentReferenceEditorDescriptor<TeaserBlock> {
  public override IEnumerable<ContentReference> Roots {
    get {
      return new ContentReference[] {
        new ContentReference(52)
      };
    }
  }
}
```

:::hint{type="info"}
**Note**
The examples in this topic control what you can drag and drop to a field, (except for the custom roots setting because it affects only what is visible on the dialog box). For example, you can drag and drop a `TeaserBlock` from a location other than under the custom root with the id 52.
:::
