I struggled so much to find how to make this work but at the end was so simple.
create a .json file with the metadata and serve it with a simple http server
ie. if your file name is metadata.json your code should look something like this
string _contractURI = "https://yourDomain.com/metadata.json"
function contractURI() public view returns (string memory) {
return _contractURI;
}
OpenSea Documentation explicitly says URL https://docs.opensea.io/docs/contract-level-metadata
Edit: I tested this solution in an ERC1155 :D I suppose is the same for ERC721