Structuring Content and Sharing Resources

This document explains some requirements of the structure of content published to Posit Connect. These are important to consider when sharing resources between different pieces of content deployed to Connect.

Content bundles

A content bundle is the directory (folder) that contains the code and other resources for a piece of content. Connect uses the bundle directory as its working directory when running the content.

When content is published to Connect, selected files are compressed and uploaded to the server, where they are extracted, preserving the hierarchical structure of files and directories. When you publish an update to a piece of content, a new bundle is created and uploaded. The old bundles are saved, and can be reactivated from the Dashboard.

Bundles are covered in more detail in the Posit Connect Server API Cookbook.

Primary target files

Most content types have primary target files that serve as the entrypoint when content is rendered or served.

Warning

The primary target file must be located at the root level of the content bundle (the directory containing the content’s resources).

The type of the primary file depends on the content type. Applications and APIs use a Python or R file as their entrypoint (e.g. app.py, app.R, plumber.R). Documents use Quarto, R Markdown, and Jupyter Notebook files (e.g. report.qmd, doc.rmd, notebook.ipynb). Websites and projects generally use metadata files (e.g. _site.yml, _quarto.yml, _bookdown.yml).

Additional files

A content bundle can also contain a number of additional files, such as additional pages (e.g. Quarto, HTML), design resources (e.g. images or CSS), datasets (e.g. CSV files) or additional source files (Python or R) used by the content. These files can be alongside the primary file in the root of the bundle directory or in subdirectories of the root directory.

Warning

Auxiliary files cannot be outside of the content bundle, and thus cannot be above the primary file in the directory hierarchy (which must be at the top level of the directory that is bundled).

Working locally, you might place shared resource files in a common directory outside of a project, and reference them with relative paths (beginning with ..). This pattern does not work when publishing to Connect. This is because the primary target for a piece of content must be at the root level of the directory that is uploaded, so files outside that directory aren’t uploaded.

Consider the following directory layout. The image project_logo.png is located outside of the directories containing the Quarto documents.

When doc1.qmd is published to Connect, the report1 directory will be bundled and uploaded. The image fig_1.png will be included in the bundle. However, the project logo, which might be referenced as ../shared/project_logo.png, cannot be included in the bundle, and any references to it will break.

# Local file structure
/report1/index.qmd
/report1/fig_1.png
/report2/index.qmd
/shared/project_logo.png

When publishing report1, the files in the report1 directory are in the resulting bundle.

# report1 content bundle
index.qmd
fig_1.png

Sharing resources between published content

For simple projects, it’s easy enough to include the files you need by placing them within the bundle directory, either alongside the primary file at the root level or in subdirectories.

For situations where multiple projects access shared resources, some common patterns that work locally do not work with published content. Review the warnings and recommendations below before publishing.

Method Works Notes
Relative paths to shared files on the deploying computer No Prohibited by Connect’s security and content execution models. See the Additional files section above.
Private packages Yes Our recommended approach for sharing code between projects. See the Private package repositories section below, and sections on Python Package Management and R Package Management.
Symlinks to shared files Sometimes This works for some deployment methods, but not for Git-backed content. Best for static assets that do not need to change between deployments. See the Symlinks to shared files section below.
Persistent storage on Connect server Yes See the Persistent storage on Posit Connect section below.
HTTP access to files Yes

Private package repositories

To share code between projects, we strongly recommend housing it in a Python or R package and making the package available to your organization. There are a number of ways to achieve this, described in detail in the Admin Guide sections on Python Package Management and R Package Management.

Persistent storage on Posit Connect

Content on Connect can access shared resources stored on the Connect server. This option is well-suited for many scenarios, such as datasets that will update.

This is described in detail in this FAQ article.