why str_replace targeting pages instead just targeting post?

Your code is returning $text only for posts and nothing for other post types like pages.

Your function should be like this

add_filter('the_content', 'replace_word');
function replace_word($text) {
        if (is_singular( 'post' )){
        $text = str_replace('dog', 'cat', $text);

        return $text;
        }

        // you must return content for pages/ other post types
        return $text;

}