Version 4 Documentation

Search WooCommerce Downloadable (PDF) Product Document Content

Note: This documentation is for SearchWP 4
SearchWP 3.x: Search WooCommerce Downloadable Product Document Content

If you’re selling document downloads in your WooCommerce store, it’s possible to have SearchWP index the content of those documents to make it searchable for your customers!

Note: this (like all document processing in SearchWP) requires that the WooCommerce Downloadable Product Downloads have been uploaded to the local WordPress Media library.

Index WooCommerce Document Content

We can take advantage of SearchWP’s ability to parse and make searchable the content from readable documents stored in the WordPress Media library. This can be paired with SearchWP’s powerful ability to index ‘extra’ metadata in its own index, without affecting the data stored in WordPress’ post or postmeta table.

The benefit to this approach will be to index the content of the WooCommerce Download(s) without exposing the entire asset.

For a more generalized example of indexing ‘extra’ data have a look at this KB article: Adding extra data to indexed entries

If you’d like to make your WooCommerce Downloadable content searchable, you can use this hook:

All hooks should be added to your custom SearchWP Customizations Plugin.

// Tell SearchWP to parse WooCommerce Downloadable Product downloads for document content.
// The content will be extracted from downloadable documents where possible and stored
// in SearchWP's index as a Custom Field with a label of "SearchWP WooCommerce Download Content"
add_filter( 'searchwp\entry\data', function( $data, \SearchWP\Entry $entry ) {
if ( 'post.product' !== $entry->get_source()->get_name() || ! class_exists( 'WC_Product' ) ) {
return $data;
$product = new \WC_Product( $entry->get_id() );
$downloads = $product->get_downloads();
if ( empty( $downloads ) ) {
return $data;
// WooCommerce only stores a hashed ID, the filename, and the URL to the file
// but we need to retrieve the Media library ID for each downloadble file.
$download_content = [];
$upload_dir = wp_upload_dir();
foreach ( $downloads as $key => $download ) {
$relative_file_location = str_replace( trailingslashit( $upload_dir['baseurl'] ), '', $download['data']['file'] );
// We can use the relative file location to retrieve the post ID we need to parse the PDFs.
$file_id = get_posts( [
'post_type' => 'attachment',
'post_status' => 'inherit',
'fields' => 'ids',
'meta_query' => [ [
'key' => '_wp_attached_file',
'value' => $relative_file_location,
], ],
] );
if ( ! empty( $file_id ) ) {
$download_content[] = \SearchWP\Document::get_content( get_post( $file_id[0] ) );
$data['meta']['swp_wc_doc_content'] = \SearchWP\Utils::tokenize( $download_content );
return $data;
}, 20, 2 );
// Add "SearchWP WooCommerce Download Content" as available option.
add_filter( 'searchwp\source\attribute\options', function( $keys, $args ) {
if ( $args['attribute'] !== 'meta' ) {
return $keys;
$content_key = 'swp_wc_doc_content';
if ( ! in_array(
array_map( function( $option ) { return $option->get_value(); }, $keys )
) ) {
$keys[] = new \SearchWP\Option( $content_key, 'SearchWP WooCommerce Download Content' );
return $keys;
}, 20, 2 );

This hook will tap into SearchWP’s indexing process and when it finds a Product with Downloads it will check those Downloads for document content and when found index that content alongside the Product itself.

This will allow you to search for the Download content and have it return the Product, not the Download, which in turn will allow your customer to make the purchase.

The last step here is to make sure you’ve added this ‘extra’ Custom Field to the Products in your SearchWP Engine, which can be done like so:

SearchWP WooCommerce download document content

Note: When using this approach you can (and likely should) disable Media from your Engine, since the Download content is being added to the Product.

With the Document content added to Products in your Engine you can click the Save Engines button, rebuild your index, and you’ll be all set!